【发布时间】:2011-08-01 21:49:58
【问题描述】:
在 numpy 中有没有办法创建一个布尔数组,每个条目只使用 1 位?
标准的np.bool类型是1字节,但是这样我使用了8倍的所需内存。
在 Google 上我发现 C++ 有 std::vector<bool>。
【问题讨论】:
在 numpy 中有没有办法创建一个布尔数组,每个条目只使用 1 位?
标准的np.bool类型是1字节,但是这样我使用了8倍的所需内存。
在 Google 上我发现 C++ 有 std::vector<bool>。
【问题讨论】:
你想要一个bitarray:
高效的布尔数组——C 扩展
这个模块提供了一个对象类型,它可以有效地表示一个布尔数组。位数组是序列类型,其行为与通常的列表非常相似。八位由一个连续的内存块中的一个字节表示。用户可以在两种表示之间进行选择;小端和大端。所有功能都用 C 语言实现。提供了访问机器表示的方法。这在需要对二进制文件进行位级访问时很有用,例如可移植位图图像文件 (.pbm)。此外,在处理使用可变位长编码的压缩数据时,您可能会发现此模块很有用...
【讨论】:
为此,您可以使用 numpy 的 packbits 和 unpackbits:
import numpy as np
# original boolean array
A1 = np.array([
[0, 1, 1, 0, 1],
[0, 0, 1, 1, 1],
[1, 1, 1, 1, 1],
], dtype=bool)
# packed data
A2 = np.packbits(A1, axis=None)
# checking the size
print(len(A1.tostring())) # 15 bytes
print(len(A2.tostring())) # 2 bytes (ceil(15/8))
# reconstructing from packed data. You need to resize and reshape
A3 = np.unpackbits(A2, count=A1.size).reshape(A1.shape).view(bool)
# and the arrays are equal
print(np.array_equal(A1, A3)) # True
在 numpy 1.17.0 之前,第一个函数可以直接使用,但重建需要额外的操作。这是一个例子:
import numpy as np
# original boolean array
A1 = np.array([
[0, 1, 1, 0, 1],
[0, 0, 1, 1, 1],
[1, 1, 1, 1, 1],
], dtype=np.bool)
# packed data
A2 = np.packbits(A1, axis=None)
# checking the size
print(len(A1.tostring())) # 15 bytes
print(len(A2.tostring())) # 2 bytes (ceil(15/8))
# reconstructing from packed data. You need to resize and reshape
A3 = np.unpackbits(A2, axis=None)[:A1.size].reshape(A1.shape).astype(np.bool)
# and the arrays are equal
print(np.array_equal(A1, A3)) # True
【讨论】: