我正在编写代码,将整数转换为填充的8位字符串然后我想把这些字符串写入一个二进制文件我无法确定当前使用的numpy数组中使用的适当dtype
在下面的代码中,当我使用bin_data设置了dtype=np.int8变量时,输出是:

$ python bool_dtype.py
a[j] = 0, bool(a[j]) = True
a[j] = 0, bool(a[j]) = True
a[j] = 0, bool(a[j]) = True
a[j] = 0, bool(a[j]) = True
a[j] = 0, bool(a[j]) = True
a[j] = 1, bool(a[j]) = True
a[j] = 0, bool(a[j]) = True
a[j] = 0, bool(a[j]) = True
a[j] = 0, bool(a[j]) = True
a[j] = 0, bool(a[j]) = True
a[j] = 0, bool(a[j]) = True
a[j] = 0, bool(a[j]) = True
a[j] = 0, bool(a[j]) = True
a[j] = 0, bool(a[j]) = True
a[j] = 0, bool(a[j]) = True
a[j] = 0, bool(a[j]) = True
[0 0 0 0 1 0 0 0 0]
16

bin_data设置为dtype=np.bool_时,输出始终为真,如下所示:
$ python bool_dtype.py
a[j] = 0, bool(a[j]) = True
a[j] = 0, bool(a[j]) = True
a[j] = 0, bool(a[j]) = True
a[j] = 0, bool(a[j]) = True
a[j] = 0, bool(a[j]) = True
a[j] = 0, bool(a[j]) = True
a[j] = 1, bool(a[j]) = True
a[j] = 1, bool(a[j]) = True
a[j] = 0, bool(a[j]) = True
a[j] = 0, bool(a[j]) = True
a[j] = 0, bool(a[j]) = True
a[j] = 0, bool(a[j]) = True
a[j] = 0, bool(a[j]) = True
a[j] = 0, bool(a[j]) = True
a[j] = 1, bool(a[j]) = True
a[j] = 1, bool(a[j]) = True
[ True  True  True  True  True  True  True  True  True]
16

当我使用dtype=np.int8查看数据的xxd转储时,我看到一个预期的字节被用来表示每个位(1,0)即00000001或00000000使用dtype=np.bool_会导致同样的问题。
所以我有两个主要问题
为什么bool在读取数组元素时总是读取为True
当我将数据写入文件时,如何才能更有效地存储数据,从而使单个位不作为字节存储,而只是连接到上一个元素上?
这是有问题的代码,谢谢!
#!/usr/bin/python2.7

import numpy as np
import os

# x = np.zeros(200,dtype=np.bool_)
# for i in range(0,len(x)):
#     if i%2 != 1:
#         x[i] = 1

data_size = 2
data = np.random.randint(0,9,data_size)
tx=''
for i in range(0,data_size):
    tx += chr(data[i])
data = tx
a = np.zeros(8,dtype=np.int8)
bin_data = np.zeros(len(data)*8,dtype=np.bool_)

# each i is a character byte in data string
for i in range(0,len(data)):
    # formats data in 8bit binary without the 0b prefix
    a = format(ord(data[i]),'b').zfill(8)
    for j in range(0,len(a)):
        bin_data[i*len(a) + j] = a[j]
        print("a[j] = {}, bool(a[j]) = {}").format(a[j], bool(a[j]))

print bin_data[1:10]
print len(bin_data)

path = os.getcwd()
path = path + '/bool_data.bin'
data_file = open(path, "wb")
data_file.write(bin_data)
data_file.close()

编辑:
使用dtype=np.bool_时我希望看到的内容
>>> import numpy as np
>>> a = np.zeros(2,dtype=np.bool_)
>>> a
array([False, False], dtype=bool)
>>> a[1] = 1
>>> a
array([False,  True], dtype=bool)

最佳答案

bool总是返回true的原因是[j]是一个非空字符串在使用bool进行测试之前(也在将其作为条目分配给numpybool数组之前),需要将[j]强制转换为int。
您可以调用numpy.packbits将布尔数组压缩为uint8数组(如果需要,它会为您填充),然后调用numpy.unpackbits来反转操作。
编辑:
如果布尔数组的长度不是8的倍数,则在打包和解包之后,将对数组进行零填充,使其长度为8的倍数。在这种情况下,您有两个选项:
如果可以安全地截断数据,使其具有可被8整除的位数,请执行此操作比如:data=data[:8*(len(data)/8)]
如果你负担不起截短,那么你将以某种方式记录有意义的位数。我建议将压缩数据的第一个字节等于mod 8中有意义的位数。这只会增加一个字节的内存开销,并且不会增加太多计算时间。类似于:
包装

bool_data = np.array([True, True, True])
nbits = len(bool_data)
rem = nbits % 8
nbytes = nbits/8
if rem: nbytes += 1
data = np.empty(1+nbytes, dtype=np.uint8)
data[0] = rem
data[1:] = np.packbits(bool_data)

拆包
rem = data[0]
bool_data = np.unpackbits(data[1:])
if rem:
  bool_data = bool_data[:-(8-rem)]

关于python - python2.7-写入磁盘时将 bool 值存储为单个位,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38622386/

10-12 00:27
查看更多