如何使用python代码从二进制文件读取和提取值?

时间:2019-05-19 06:38:27

标签: python python-3.x python-2.7 binaryfiles astronomy

我对python比较陌生。作为天文学项目工作的一部分,我必须处理二进制文件(这当然对我来说还是新的)。给了我一个二进制文件和一个从二进制文件中读取数据的python代码。然后,我的教授要求我了解代码如何在二进制文件上工作。我花了几天的时间试图弄清楚,但没有任何帮助。这里有人可以帮助我提供代码吗?

# Read the binary opacity file
f = open(file, "r")

# read file dimension sizes
a = np.fromfile(f, dtype=np.int32, count=16)
NX, NY, NZ = a[1], a[4], a[7]


# read the time and time step
time, time_step = np.fromfile(f, dtype=np.float64, count=2)

# number of iterations
nite = np.fromfile(f, dtype=np.int32, count=1)

# radius array
trash = np.fromfile(f, dtype=np.float64, count=1)
rad = np.fromfile(f, dtype=np.float64, count=a[1])

# phi array
trash = np.fromfile(f, dtype=np.float64, count=1)
phi = np.fromfile(f, dtype=np.float64, count=a[4])

# close the file
f.close()

据我所知,二进制文件包含几个参数(例如:半径,phi,声速,辐射能量)及其许多值。上面的代码从二进制文件中提取值2参数-radius和phi。半径和phi都有超过100个值。该程序有效,但我无法理解其工作原理。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:0)

二进制文件本质上只是一长串连续数据;您需要同时告诉np.fromfile()在哪里查看期望的数据类型。 如果您创建自己的文件,也许最容易理解:

import numpy as np

with open('numpy_testfile', 'w+') as f:
    ## we create a "header" line, which collects the lengths of all relevant arrays
    ## you can then use this header line to tell np.fromfile() *how long* the arrays are
    dimensions=np.array([0,10,0,0,10,0,3,10],dtype=np.int32)
    dimensions.tofile(f) ## write to file

    a=np.arange(0,10,1) ## some fake data, length 10
    a.tofile(f) ## write to file
    print(a.dtype)

    b=np.arange(30,40,1) ## more fake data, length 10
    b.tofile(f) ## write to file
    print(b.dtype)

    ##  more interesting data, this time it's of type float, length 3
    c=np.array([3.14,4.22,55.0],dtype=np.float64) 
    c.tofile(f) ## write to file
    print(c.dtype)

    a.tofile(f) ## just for fun, let's write "a" again

with open('numpy_testfile', 'r+b') as f:
    ### what's important to know about this step is that 
    #   numpy is "seeking" the file automatically, i.e. it is considering 
    #   the first count=8, than the next count=10, and so on 
    #   as "continuous data"
    dim=np.fromfile(f,dtype=np.int32,count=8)
    print(dim) ## our header line: [ 0 10  0  0 10  0  3 10]
    a=np.fromfile(f,dtype=np.int64,count=dim[1])## read the dim[1]=10 numbers
    b=np.fromfile(f,dtype=np.int64,count=dim[4])## and the next 10
    ## now it's dim[6]=3, and the dtype is float 10
    c=np.fromfile(f,dtype=np.float64,count=dim[6] )#count=30)
    ## read "the rest", unspecified length, let's hope it's all int64 actually!
    d=np.fromfile(f,dtype=np.int64) 

print(a)
print(b)
print(c)
print(d)

附录:在{strong>禁止np.tofile()np.fromfile()的使用方面,numpy documentation非常明确:

  

请勿依赖于tofile和fromfile的组合进行数据存储,因为生成的二进制文件不是平台无关的。特别是,不保存字节顺序或数据类型信息。可以使用保存和加载方式以独立于平台的.npy格式存储数据。

个人注意事项::如果您花了几天时间来理解该代码,请不要灰心学习python;我们都从某个地方开始。我建议您对教授遇到的障碍(如果这是在对话中遇到的)坦诚相待,因为他/他在编程时应该能够正确断言“您在哪里”。 :-)

答案 1 :(得分:0)

from astropy.io import ascii    
data = ascii.read('/directory/filename')
column1data = data[nameofcolumn1]
column2data = data[nameofcolumn2]

等 现在column1data是该标头下所有值的数组 我使用这种方法导入ASCII格式的SourceExtractor dat文件。 我相信这是一种从ASCII文件导入数据的更优雅的方式。