【问题标题】:Python-numpy reading bytes and offset to signed int32Python-numpy 读取字节和偏移到有符号的 int32
【发布时间】:2022-01-07 12:51:30
【问题描述】:

我有一个操作要在 python 中应用于超过 1000 万个值。我的问题是优化实际操作。 我有 2 种工作方法,numpy 和 python vanilla。

Python 原版操作:

  • 1:我的原始值为 4 byte 数据:b'\x9a#\xe6\x00' = [154, 35, 230, 0] = [0x9A, 0x23, 0xE6, 0x00]
  • 2:我取最后一个字节放在最前面:b'\x00\x9a#\xe6'=[0, 154, 35, 230]=[0x00, 0x9A, 0x23, 0xE6]
  • 3:我将其转换为 int32 有符号值:-433874432

文件加载:

f = open(path_data, "rb")
while trame := f.read(4):

数据操作:

trame = b'\x9a#\xe6\x00'
trame_list = list(trame)  # [154, 35, 230, 0]
trame_list_swap = [trame_list[-1]] + trame_list[:-1]
trame_swap = bytes(trame_list_swap)
result = int.from_bytes(trame_swap, byteorder='little', signed=True)

Numpy 操作


文件加载:

datas_raw = numpy.fromfile(path_data, dtype="<i4")
# datas_raw = numpy.array([-1708923392, 1639068928, 2024603392, ...])  # len(datas_raw) = 12171264
for i, trame in enumerate(datas_raw):

数据操作:

trame = 15082394
tmp = list(trame.tobytes("C"))
tmp.insert(0, tmp.pop())
result = numpy.ndarray(1, "<i", bytes(tmp))[0]

由于numpy.ndarray 被触发了 1000 万次,它的处理速度与原版相同,但速度较慢...

问题

我的问题如下:

我希望 numpy 版本在没有 for loop 的情况下对所有值进行按位运算(在 python 中非常慢)......欢迎任何其他解决方案(不是关闭 XY 问题......)

【问题讨论】:

    标签: python numpy binary binaryfiles byte-shifting


    【解决方案1】:

    这里我使用一些随机数据代替从文件中读取的数据,您可以使用np.loadtxt 来完成。理想情况下,您可以将字节读入形状为 (4*n,) 的一维数组,然后重新整形为 (n,4)

    import numpy as np
    rng = np.random.default_rng(0)
    data = rng.integers(-2**31,2**31,size=10000,dtype="i4")
    data = data.view("u1").reshape((-1,4))
    # Last column first, then other 3
    data = data[:,[3,0,1,2]]
    # Depending on platform might need to specify byteorder, e.g., "<i4" or ">i4"
    ints = np.ascontiguousarray(data).view("i4")
    

    这会产生类似的值

    array([[-1031643175],
           [  267112355],
           [ -640212606],
           ...,
    

    这将返回一个形状为 (n,1) 的有符号整数数组。

    【讨论】:

    • 感谢您的回答,我的变量datas_rawnumpy.array([-1708923392, 1639068928, 2024603392, ...]) 要获得4 个int8 的列表,我必须申请list(trame.tobytes("C")),但是如何在没有for 循环的情况下做到这一点?您的回答很有用,但我与输入不匹配...
    • 我更改了答案以反映您的输入数据结构。您只需要一个view 来使其成为字节,然后是枢轴,然后是第二个视图。
    • 哇!看来这正是我所需要的!我对其进行测试,如果可以,请完全支持您的答案!谢谢
    • 这个过程现在快了 80 倍,谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-02
    • 2013-01-03
    • 1970-01-01
    • 2015-03-16
    相关资源
    最近更新 更多