亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

在python中讀取二進制數據文件以進行分析

在python中讀取二進制數據文件以進行分析

三國紛爭 2022-08-02 18:42:17
我使用Fortran以以下格式將數據寫入二進制文件open(unit=99,form='unformatted',status='unknown')do i=1,Nwrite(99) (i),(A(i)),(B(i))enddoclose(99)這里,A 和 B 是雙精度數組。如何在python中讀取此二進制數據文件?PS:到目前為止,我嘗試了以下步驟來讀取數據。with open('fort.99', 'rb') as binfile:    data=binfile.read()雖然文件讀取是成功的,但我無法對此數據使用函數,這是我大多數分析的首選。numpy
查看完整描述

1 回答

?
qq_笑_17

TA貢獻1818條經驗 獲得超7個贊

更新的答案


我在Numpy中對此進行了更多嘗試,您可以像這樣更干凈地閱讀文件 - 以下信息仍然適用并解釋了它的工作原理:


import numpy as np


# Read file and reshape as "records" of 28 bytes each

n = np.fromfile('fort.99',dtype=np.uint8).reshape(-1,28)

I = n[:,4:8].copy().view(np.int32)     # pick bytes 4-8, make contiguous and view as integer

A = n[:,8:16].copy().view(np.float64)  # pick bytes 8-16, make contiguous and view as float64

B = n[:,16:24].copy().view(np.float64) # pick bytes 16-24, make contiguous and view as float64

原始答案


我更改了您的程序以包含一些可識別的數據:


      program thing

      REAL*8, DIMENSION(128) :: A,B

      INTEGER N

      N=128


      open(unit=99,form='unformatted',status='unknown')

      do i=1,N

      A(i)=100.0 * i

      B(i)=-1000.0 * i

      write(99) (2*i),(A(i)),(B(i))

      enddo

      close(99)

      end program

然后我查看了文件大小,它是3,584字節,所以我將其除以128,以獲得每個fortran的字節數為28。WRITE


因此,按如下方式檢查了數據:xxd


xxd -c 28 fort.99


00000000: 1400 0000 0200 0000 0000 0000 0000 5940 0000 0000 0040 8fc0 1400 0000  ..............Y@.....@......

0000001c: 1400 0000 0400 0000 0000 0000 0000 6940 0000 0000 0040 9fc0 1400 0000  ..............i@.....@......

00000038: 1400 0000 0600 0000 0000 0000 00c0 7240 0000 0000 0070 a7c0 1400 0000  [email protected]......

00000054: 1400 0000 0800 0000 0000 0000 0000 7940 0000 0000 0040 afc0 1400 0000  ..............y@.....@......

00000070: 1400 0000 0a00 0000 0000 0000 0040 7f40 0000 0000 0088 b3c0 1400 0000  .............@.@............

0000008c: 1400 0000 0c00 0000 0000 0000 00c0 8240 0000 0000 0070 b7c0 1400 0000  [email protected]......

000000a8: 1400 0000 0e00 0000 0000 0000 00e0 8540 0000 0000 0058 bbc0 1400 0000  [email protected]......

000000c4: 1400 0000 1000 0000 0000 0000 0000 8940 0000 0000 0040 bfc0 1400 0000  ...............@.....@......

000000e0: 1400 0000 1200 0000 0000 0000 0020 8c40 0000 0000 0094 c1c0 1400 0000  ............. .@............

000000fc: 1400 0000 1400 0000 0000 0000 0040 8f40 0000 0000 0088 c3c0 1400 0000  .............@.@............

因此,每個 fortran WRITE 有 28 個字節,每個記錄的開頭和結尾有 4 個字節的索引。


然后我像這樣解碼它們:


#!/usr/bin/env python3


import struct


# Important to open the file in binary mode, 'b'

with open('fort.99','rb') as f:

     # You should really read until error in case there are more or fewer than 128 records one day - but you know there are 128


    for i in range(128):

        # Read one record, i.e. output of one fortran WRITE

        record = f.read(28)

        # Unpack 2 INTEGERs, 2 DOUBLEs and an INTEGER

        _, I, A, B, _ = struct.unpack('2i2di',record)

        print(I,A,B)

輸出


2 100.0 -1000.0

4 200.0 -2000.0

6 300.0 -3000.0

8 400.0 -4000.0

10 500.0 -5000.0

12 600.0 -6000.0

14 700.0 -7000.0

16 800.0 -8000.0

18 900.0 -9000.0

20 1000.0 -10000.0

22 1100.0 -11000.0

24 1200.0 -12000.0

26 1300.0 -13000.0

28 1400.0 -14000.0

30 1500.0 -15000.0

32 1600.0 -16000.0

34 1700.0 -17000.0

36 1800.0 -18000.0

38 1900.0 -19000.0

40 2000.0 -20000.0

42 2100.0 -21000.0

44 2200.0 -22000.0

46 2300.0 -23000.0

48 2400.0 -24000.0

50 2500.0 -25000.0

52 2600.0 -26000.0

54 2700.0 -27000.0

56 2800.0 -28000.0

58 2900.0 -29000.0

60 3000.0 -30000.0

62 3100.0 -31000.0

64 3200.0 -32000.0

66 3300.0 -33000.0

68 3400.0 -34000.0

70 3500.0 -35000.0

72 3600.0 -36000.0

74 3700.0 -37000.0

76 3800.0 -38000.0

78 3900.0 -39000.0

80 4000.0 -40000.0

82 4100.0 -41000.0

84 4200.0 -42000.0

86 4300.0 -43000.0

88 4400.0 -44000.0

90 4500.0 -45000.0

92 4600.0 -46000.0

94 4700.0 -47000.0

96 4800.0 -48000.0

98 4900.0 -49000.0

100 5000.0 -50000.0

102 5100.0 -51000.0

104 5200.0 -52000.0

106 5300.0 -53000.0

108 5400.0 -54000.0

110 5500.0 -55000.0

112 5600.0 -56000.0

114 5700.0 -57000.0

116 5800.0 -58000.0

118 5900.0 -59000.0

120 6000.0 -60000.0

122 6100.0 -61000.0

124 6200.0 -62000.0

126 6300.0 -63000.0

128 6400.0 -64000.0

130 6500.0 -65000.0

132 6600.0 -66000.0

134 6700.0 -67000.0

136 6800.0 -68000.0

138 6900.0 -69000.0

140 7000.0 -70000.0

142 7100.0 -71000.0

144 7200.0 -72000.0

146 7300.0 -73000.0

148 7400.0 -74000.0

150 7500.0 -75000.0

152 7600.0 -76000.0

154 7700.0 -77000.0

156 7800.0 -78000.0

158 7900.0 -79000.0

160 8000.0 -80000.0

162 8100.0 -81000.0

164 8200.0 -82000.0

166 8300.0 -83000.0

168 8400.0 -84000.0

170 8500.0 -85000.0

172 8600.0 -86000.0

174 8700.0 -87000.0

176 8800.0 -88000.0

178 8900.0 -89000.0

180 9000.0 -90000.0

182 9100.0 -91000.0

184 9200.0 -92000.0

186 9300.0 -93000.0

188 9400.0 -94000.0

190 9500.0 -95000.0

192 9600.0 -96000.0

194 9700.0 -97000.0

196 9800.0 -98000.0

198 9900.0 -99000.0

200 10000.0 -100000.0

202 10100.0 -101000.0

204 10200.0 -102000.0

206 10300.0 -103000.0

208 10400.0 -104000.0

210 10500.0 -105000.0

212 10600.0 -106000.0

214 10700.0 -107000.0

216 10800.0 -108000.0

218 10900.0 -109000.0

220 11000.0 -110000.0

222 11100.0 -111000.0

224 11200.0 -112000.0

226 11300.0 -113000.0

228 11400.0 -114000.0

230 11500.0 -115000.0

232 11600.0 -116000.0

234 11700.0 -117000.0

236 11800.0 -118000.0

238 11900.0 -119000.0

240 12000.0 -120000.0

242 12100.0 -121000.0

244 12200.0 -122000.0

246 12300.0 -123000.0

248 12400.0 -124000.0

250 12500.0 -125000.0

252 12600.0 -126000.0

254 12700.0 -127000.0

256 12800.0 -128000.0

如您所見,每條記錄上都有記錄標記,這意味著記錄的長度為20個字節(1個fortran INTEGER@4,2個fortran DOUBLE@8),每端都有4個字節的記錄標記 - 我將其讀入Python中調用并丟棄的變量中。如果你不想要這樣,你需要在fortran中使用/輸出 - 但我不知道你是否可以在處理鏈的另一端控制它。有關說明,請參閱此處。1400 0000_DIRECTSTREAM


關鍵字: fortran, Python, 二進制, 無格式, xxd, 轉儲, 記錄, 視圖為整數, 視圖為浮點數, 視圖為浮點64, 視圖為雙精度


查看完整回答
反對 回復 2022-08-02
  • 1 回答
  • 0 關注
  • 191 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號