【问题标题】:Using numpy fromfile on binary file returns 1 dimension ndarray在二进制文件上使用 numpy fromfile 返回一维 ndarray
【发布时间】:2013-11-26 04:43:56
【问题描述】:

我正在使用 numpy 的 fromfile 函数从二进制文件中读取数据。该文件包含一系列值 (3 * float32, 3 * int8, 3 * float32),我想将其提取到具有 (rows, 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. 如何获得形状为 (38475732, 9,) 的二维 ndarray?

  2. 为什么返回的元组是“numpy.void”类型的?

重新定义问题:

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

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

解决办法:

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

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

干杯!

【问题讨论】:

  • sys.byteorder 的值是多少?
  • 它返回“小”,但我不明白为什么这很重要......
  • 你正在使用'>',它是大端的。您是否尝试使用“
  • 我在元组中得到的值是正确的。问题在于定义映射到 2d ndarray 的 dtype 表达式

标签: python numpy


【解决方案1】:

my_array[[0]] 是什么? my_array 是由my_dtype 定义的一维记录数组。

my_array[0] 是这些记录之一,一个元组。请注意,有些条目是浮点数,有些是整数。如果它是二维数组的一行,则所有条目都属于同一类型(例如浮点数)。

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

np.array(my_array.tolist())

另一种方法是将所有字段转换为相同的类型,并对其进行重塑。沿着这条线的东西(在不同的recarray上测试):

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?

【讨论】:

  • my_array[[0]] = [(-775.0602416992188, -71.0, -242.5240020751953, 39, 39, 39, 5.0, 2753.0, 15328.0)]
【解决方案2】:

由于您需要数组包含不同的数据类型,因此您会得到一个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 包含相同类型的元素,如果您需要形状为 (38475732, 9,) 的 ndarray,则必须将数组转换为浮点数。见上面的链接。

无法确切说明原因(没有太多使用结构化数组),但numpy.void 的原因是您的自定义类型(数组已知)未广播到记录。但是子记录的类型是什么?

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-07-19
    • 2014-09-20
    • 2013-04-10
    • 1970-01-01
    • 1970-01-01
    • 2021-10-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多