gpt4 book ai didi

python - 从 numpy.int32 数组的数据字节中有效地删除每 4 个字节

转载 作者:行者123 更新时间:2023-12-03 21:49:42 28 4
gpt4 key购买 nike

我有一个大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'
    但是很多reshapex 时效率低下有几 GB 大:它需要大量不需要的 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,对于 sx (也许还有 x.tostring() ?)

  • TL;博士: 如何通过删除每 4 个字节来有效地(不使用两倍于实际数据大小的 RAM)将一个 int32 数组作为 24 位数组写入磁盘?
    注意:这是可能的,因为整数实际上是 24 位的,即每个值的绝对值 < 2^23-1

    最佳答案

    经过更多的摆弄,我发现这是有效的:

    import numpy as np
    x = np.array([[-33772,-2193],[13313,-1314],[20965,-1540],[10706,-5995],[-37719,-5871]], dtype=np.int32)
    x2 = x.view(np.uint8).reshape(-1,4)[:,:3]
    print(x2.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'
    这是一个时间+内存基准:
    import numpy as np, time
    t0 = time.time()
    x = np.random.randint(10000, size=(125_000_000, 2), dtype=np.int32) # 125M * 2 * 4 bytes ~ 1GB of RAM
    print('Random array generated in %.1f sec.' % (time.time() - t0))
    time.sleep(5)
    # you can check the RAM usage in the task manager in the meantime...
    t0 = time.time()
    x2 = x.view(np.uint8).reshape(-1,4)[:,:3]
    x2.tofile('test')
    print('24-bit output file written in %.1f sec.' % (time.time() - t0))
    结果:

    Random array generated in 4.6 sec.
    24-bit output file written in 35.9 sec.


    此外,在整个处理过程中仅使用了约 1GB(使用 Windows 任务管理器进行监控)

    @jdehesa 的方法给出了类似的结果,即如果我们改用这一行:
    x2 = np.ndarray(shape=x.shape + (3,), dtype=np.uint8, buffer=x, offset=0, strides=x.strides + (1,))
    该进程的 RAM 使用量也达到了 1GB 的峰值,并且花费的时间在 x2.tofile(...) 上。是 ~37 秒。

    关于python - 从 numpy.int32 数组的数据字节中有效地删除每 4 个字节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63156701/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com