我有一个大numpy.int32
阵列,可能需要 4GB 或更多。它实际上是一个24 位整数数组(在音频应用程序中很常见),但由于numpy.int24
不存在,我使用了int32
.
我想将此数组的数据作为 24 位(即每个数字 3 个字节)输出到文件中。
这行得通(我不久前在某个地方找到了这个“食谱”,但我再也找不到了):
import numpy as np x = np.array([[-33772,-2193],[13313,-1314],[20965,-1540],[10706,-5995],[-37719,-5871]], dtype=np.int32) data = ((x.reshape(x.shape + (1,)) >> np.array([0, 8, 16])) & 255).astype(np.uint8) print(data.tostring()) # b'\x14|\xffo\xf7\xff\x014\x00\xde\xfa\xff\xe5Q\x00\xfc\xf9\xff\xd2)\x00\x95\xe8\xff\xa9l\xff\x11\xe9\xff'
但是当只有几 GB 时,许多
reshape
会使其效率低下x
:它需要大量不需要的 RAM。另一种解决方案是删除每 4 个字节:
s = bytes([c for i, c in enumerate(x.tostring()) if i % 4 != 3]) # b'\x14|\xffo\xf7\xff\x014\x00\xde\xfa\xff\xe5Q\x00\xfc\xf9\xff\xd2)\x00\x95\xe8\xff\xa9l\xff\x11\xe9\xff'
它可以工作,但我怀疑如果
x
需要 4 GB 的 RAM,这条线将至少消耗 8 GB 的 RAM,对于两者s
和x
(也许还有x.tostring()
?)
TL;DR:如何通过删除每 4 个字节有效地(不使用两倍于实际数据大小的 RAM)将 int32 数组作为 24 位数组写入磁盘?
注意:这是可能的,因为整数实际上是 24 位的,即每个值的绝对值 < 2^23-1