读/写从/二进制文件Python列表(Read/Write Python List from/to

2019-09-26 02:43发布

根据Python的食谱,下面是怎么写的解析成二进制文件的列表:

from struct import Struct
def write_records(records, format, f):
    '''
    Write a sequence of tuples to a binary file of structures.
    '''
    record_struct = Struct(format)
    for r in records:
        f.write(record_struct.pack(*r))

# Example
if __name__ == '__main__':
    records = [ (1, 2.3, 4.5),
                (6, 7.8, 9.0),
                (12, 13.4, 56.7) ]
    with open('data.b', 'wb') as f:
        write_records(records, '<idd', f)

而且效果很好。 对于阅读(大量的二进制数据),笔者提出以下建议:

>>> import numpy as np
>>> f = open('data.b', 'rb')
>>> records = np.fromfile(f, dtype='<i,<d,<d')
>>> records
array([(1, 2.3, 4.5), (6, 7.8, 9.0), (12, 13.4, 56.7)],
dtype=[('f0', '<i4'), ('f1', '<f8'), ('f2', '<f8')])
>>> records[0]
(1, 2.3, 4.5)
>>> records[1]
(6, 7.8, 9.0)
>>>

这也不错,但是这record是不是一个正常的numpy的阵列。 例如, type(record[0])将返回<type 'numpy.void'> 更糟的是,我无法通过提取第一列X = record[:, 0]

有一种方法,以从二进制文件列表(或任何其它类型的)有效地加载到正常numpy的数组? THX提前。

Answer 1:

In [196]: rec = np.fromfile('data.b', dtype='<i,<d,<d')
In [198]: rec
Out[198]: 
array([( 1,   2.3,   4.5), ( 6,   7.8,   9. ), (12,  13.4,  56.7)], 
      dtype=[('f0', '<i4'), ('f1', '<f8'), ('f2', '<f8')])

这是一维结构化阵列

In [199]: rec['f0']
Out[199]: array([ 1,  6, 12], dtype=int32)
In [200]: rec.shape
Out[200]: (3,)
In [201]: rec.dtype
Out[201]: dtype([('f0', '<i4'), ('f1', '<f8'), ('f2', '<f8')])

需要注意的是其tolist看起来与原来的records

In [202]: rec.tolist()
Out[202]: [(1, 2.3, 4.5), (6, 7.8, 9.0), (12, 13.4, 56.7)]
In [203]: records
Out[203]: [(1, 2.3, 4.5), (6, 7.8, 9.0), (12, 13.4, 56.7)]

你可以创建从任一列表二维数组:

In [204]: arr2 = np.array(rec.tolist())
In [205]: arr2
Out[205]: 
array([[  1. ,   2.3,   4.5],
       [  6. ,   7.8,   9. ],
       [ 12. ,  13.4,  56.7]])
In [206]: arr2.shape
Out[206]: (3, 3)

有转换结构数组到“常规”阵列的其他方法,但是这是最简单,最一致的。

tolist规则阵列使用嵌套列表。 在结构化版本的元组是为了传达一个区别:

In [207]: arr2.tolist()
Out[207]: [[1.0, 2.3, 4.5], [6.0, 7.8, 9.0], [12.0, 13.4, 56.7]]

在结构化阵列的第一个字段是整数。 在常规阵列的第一列是相同他人,浮子。

如果二进制文件包含了所有的花车,你可以加载它作为花车的一维和重塑

In [208]: with open('data.f', 'wb') as f:
     ...:         write_records(records, 'ddd', f)
In [210]: rec2 = np.fromfile('data.f', dtype='<d')
In [211]: rec2
Out[211]: array([  1. ,   2.3,   4.5,   6. ,   7.8,   9. ,  12. ,  13.4,  56.7])

但是,利用任何记录结构的二进制文件,您可以通过记录具有负载为好,这意味着结构数组:

In [213]: rec3 = np.fromfile('data.f', dtype='d,d,d')
In [214]: rec3
Out[214]: 
array([(  1.,   2.3,   4.5), (  6.,   7.8,   9. ), ( 12.,  13.4,  56.7)], 
      dtype=[('f0', '<f8'), ('f1', '<f8'), ('f2', '<f8')])


文章来源: Read/Write Python List from/to Binary file