numpy.array.tofile() 二进制文件在记事本++中看起来“奇怪”

问题描述 投票:0回答:2

我只是想知道该函数实际上如何存储数据。因为对我来说,它看起来完全奇怪。假设我有以下代码:

import numpy as np
filename = "test.dat"
print(filename)
fileobj = open(filename, mode='wb')
off = np.array([1, 300], dtype=np.int32)
off.tofile(fileobj)
fileobj.close()

fileobj2 = open(filename, mode='rb')
off = np.fromfile(fileobj2, dtype = np.int32)
print(off)
fileobj2.close()

现在我期望文件内有 8 个字节,其中每个元素由 4 个字节表示(并且我可以接受任何字节序)。但是,当我在十六进制编辑器中打开文件(使用带有十六进制编辑器插件的记事本++)时,我得到以下字节:

01 00 C4 AC 00

5个字节,我根本不知道它代表什么。第一个字节看起来像是数字,但接下来的内容很奇怪,肯定不是“300”。

但是重新加载会显示原始数组。

这是我在python中不明白的东西,还是在notepad++中的问题? - 我注意到如果我选择不同的“编码”,十六进制看起来会有所不同(嗯?)。另外:Windows 确实报告它的长度为 8 个字节。

python numpy notepad++ hexdump
2个回答
2
投票

您可以很容易地看出该文件实际上确实有8个字节,与您期望的相同8个字节(

01 00 00 00 2C 01 00 00
),只需使用Notepad++以外的任何东西来查看该文件,包括仅替换您的
off = np.fromfile(fileobj2, dtype=np.int32)
使用
off = fileobj2.read()
然后
print
字节(这会给你
b'\x01\x00\x00\x00,\x01\x00\x00'
1))。

而且,从你的评论来看,在我建议之后,你尝试了一下,并且看到了这一点。

这意味着这要么是 Notepad++ 中的错误,要么是您使用它的方式有问题; Python、NumPy 和您自己的代码都很好。


1) 如果不清楚:

'\x2c'
','
是同一个字符,并且
bytes
使用可打印 ASCII 表示形式来表示可打印 ASCII 字符,以及尽可能使用熟悉的转义符,如
'\n'
,仅对其他值使用十六进制反斜杠转义。


1
投票

您期望

300
是什么样子?

写入数组,并将其以二进制形式读回(在 ipython 中):

In [478]: np.array([1,300],np.int32).tofile('test')

In [479]: with open('test','rb') as f: print(f.read())
b'\x01\x00\x00\x00,\x01\x00\x00'

有8个字节,

,
只是一个可显示的字节。

实际上,我不需要通过文件来得到这个:

In [505]: np.array([1,300]).tostring()
Out[505]: b'\x01\x00\x00\x00,\x01\x00\x00'

执行同样的操作:

[255]    
b'\xff\x00\x00\x00'

[256]
b'\x00\x01\x00\x00'

[300]
b',\x01\x00\x00'

[1,255]
b'\x01\x00\x00\x00\xff\x00\x00\x00'

使用 2 的幂(以及更少的 1),很容易识别字节中的模式。


frombuffer
将字节字符串转换回数组:

In [513]: np.frombuffer(np.array([1,300]).tostring(),int)
Out[513]: array([  1, 300])

In [514]: np.frombuffer(np.array([1,300]).data,int)
Out[514]: array([  1, 300])

从最后一个表达式来看,

tofile
只是将数组缓冲区以字节形式写入文件。

© www.soinside.com 2019 - 2024. All rights reserved.