在二进制文件上使用numpy fromfile返回1维ndarray

时间:2013-11-26 04:43:57

标签: python numpy

我正在使用numpy的fromfile函数从二进制文件中读取数据。该文件包含一系列值(3 * float32,3 * int8,3 * float32),我想将其提取为具有(行,9)形状的numpy ndarray。

with open('file/path', 'rb') as my_file:
    my_dtype = np.dtype('>f4, >f4, >f4, >i1, >i1, >i1, >f4, >f4, >f4' )
    my_array = np.fromfile( my_file, dtype = my_dtype )

    print(my_array.shape)
    print(type(my_array[0]))
    print(my_array[0])

然后返回:

(38475732,)
<type 'numpy.void'>
(-775.0602416992188, -71.0, -242.5240020751953, 39, 39, 39, 5.0, 2753.0, 15328.0)
  1. 如何获得具有形状的二维ndarray(38475732,9?)?

  2. 为什么返回的元组的类型为'numpy.void'?

  3. 重新定义问题:

    如果我想从文件中读取的所有值都是,例如,4字节浮点数,我将使用np.dtype('9&gt; f4'),我会得到我需要的。但是,由于我的二进制文件包含不同的类型,有没有办法将所有值转换为32位浮点数?

    PS:我可以使用'struct'将二进制文件解析为一个列表,然后将此列表转换为ndarray,但这种方法比使用np.fromfile要慢得多

    解决方案:

    感谢Hpaulj的回答!我在我的代码中做的是添加以下行来执行从numpy fromfile函数返回到预期的ndarray的recarray的转换:

    my_array = my_array.astype('f4, f4, f4, f4, f4, f4, f4, f4, f4').view(dtype='f4').reshape(my_array.shape[0], 9)
    

    返回(38475732,9)ndarray

    干杯!

2 个答案:

答案 0 :(得分:2)

什么是my_array[[0]]my_array是由my_dtype定义的1d记录数组。

my_array[0]是其中一个记录,一个元组。请注意,有些条目是浮点数,有些是整数。如果它是一个2d数组的行,则所有条目都是相同的类型(例如float)。

要将其转换为2d浮点数组,您可以尝试:

np.array(my_array.tolist())

另一种方法是将所有字段转换为相同的类型,并重新整形。沿着这条线的东西(在不同的重新测试中测试):

x = array([(1.0, 2), (3.0, 4)], dtype=[('x', '<f8'), ('y', '<i4')])
x.astype([('x', '<f8'), ('y', '<f8')]).view(dtype='f8').reshape(2,2)

另请参阅:How to convert numpy.recarray to numpy.array?

答案 1 :(得分:0)

由于您需要包含不同数据类型的数组,因此得到structured array,其中每个元素都是一条记录。您可以使用

访问字段
>>> my_array.dtype.names
('f0', 'f1', 'f2', 'f3', 'f4', 'f5', 'f6', 'f7', 'f8')
>>> my_array[0]['f1']
-71.0
>>> my_array['f1']
array([-71.], dtype=float32)

基本ndarray包含相同类型的元素,如果需要带形状的ndarray(38475732,9,),则必须将数组转换为浮点数。见上面的链接。

不能确切地说明原因(没有使用结构化数组),但numpy.void的原因是数组已知的自定义类型不会广播到记录中。但是什么类型的子记录呢?

>>> arr[['f0','f1']][0]
(-775.0602416992188, -71.0)