我正在寻找更紧凑的方式来存储 bool 值。
numpy 内部需要 8 位来存储一个 bool 值,但是 np.packbits
允许打包
他们,这很酷。
问题是,要在 4e6 字节 数组中打包一个 32e6 字节 bool 数组,我们需要先花费 256e6 字节 来转换int 数组中的 bool 数组!
In [1]: db_bool = np.array(np.random.randint(2, size=(int(2e6), 16)), dtype=bool)
In [2]: db_int = np.asarray(db_bool, dtype=int)
In [3]: db_packed = np.packbits(db_int, axis=0)
In [4]: db.nbytes, db_int.nbytes, db_packed.nbytes
Out[5]: (32000000, 256000000, 4000000)
在 numpy 跟踪器中打开了一个一年前的问题(Cf. https://github.com/numpy/numpy/issues/5377 )
有人有解决方案/更好的解决方法吗?
当我们尝试以正确的方式进行时的回溯:
In [28]: db_pb = np.packbits(db_bool)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-28-3715e167166b> in <module>()
----> 1 db_pb = np.packbits(db_bool)
TypeError: Expected an input array of integer data type
In [29]:
PS:我会尝试使用 bitarray,但会在纯 numpy 中得到它。
最佳答案
无需将 bool 数组转换为 native int
dtype(在 x86_64 上为 64 位)。您可以通过将其视为 np.uint8
来避免复制 bool 数组,每个元素也使用一个字节:
packed = np.packbits(db_bool.view(np.uint8))
unpacked = np.unpackbits(packed)[:db_bool.size].reshape(db_bool.shape).view(np.bool)
print(np.all(db_bool == unpacked))
# True
此外,自 this commit 起,np.packbits
现在应该可以直接在 bool 数组上工作来自一年多以前(numpy v1.10.0 和更新版本)。
关于python - 打包 bool 数组需要通过 int (numpy 1.8.2),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34511362/