gpt4 book ai didi

python - 将 numpy 数组重新排序为新的位长度元素,无需循环

转载 作者:行者123 更新时间:2023-12-02 18:31:51 26 4
gpt4 key购买 nike

如果我有一个 numpy 数组,其中每个元素代表例如一个 9 位整数,是否有一种简单的方法(可能没有循环)对其进行重新排序,使得结果数组元素每个都代表一个 8 位整数,并在前一个元素的末尾添加“丢失的位”在下一个元素的开头?例如得到以下内容

np.array([0b100111000, 0b100101100, 0b110011100, 0b110010100])  # initial array in binarys
# convert to
np.array([0b10011100, 0b01001011, 0b00110011, 0b10011001, 0b01000000]) # resulting array

我希望人们可以理解我想要存档的内容。附加信息,我不知道这是否有什么区别:我所有的 9 位数字都以 MSB 为 1 开头(它们大于 255),最后两位始终为 0,如上面的示例所示。我想要处理的数组要大得多,有数千个元素。

提前感谢您的帮助!

编辑:

我当前(复杂)的解决方案如下:

import numpy as np
def get_bits(data, offset, leng):
data = (data % (1 << (offset + leng))) >> offset
return data

data1 = np.array([0b100111000, 0b100101100, 0b110011100, 0b110010100])
i = 1
part1 = []
part2 = []
for el in data1:
if i == 1:
part2.append(0)
part1.append(get_bits(el, i, 8))
part2.append(get_bits(el, 0, i)<<(8-i))
if i == 8:
i = 1
part1.append(0)
else:
i += 1
if i != 1:
part1.append(0)
res = np.array(part1) + np.array(part2)

最佳答案

np.packbits 一直困扰着我。和np.unpackbits效率低下,所以我想出了一个有点麻烦的答案。

总体思路是像任何重采样器一样工作:创建一个输出数组,并找出每部分输出来自输入的位置。您有N每个元素为 9 位,因此输出为:

data = np.array([0b100111000, 0b100101100, 0b110011100, 0b110010100])
result = np.empty(np.ceil(data.size * 9 / 8).astype(int), dtype=np.uint8)

每九个输出字节相对于相应的八个输入字节具有以下模式。我用{...}指示每个输入整数中的(含)位:

result[0] =              data[0]{8:1}
result[1] = data[0]{0:0} data[1]{8:2}
result[2] = data[1]{1:0} data[2]{8:3}
result[3] = data[2]{2:0} data[3]{8:4}
result[4] = data[3]{3:0} data[4]{8:5}
result[5] = data[4]{4:0} data[5]{8:6}
result[6] = data[5]{5:0} data[6]{8:7}
result[7] = data[6]{6:0} data[7]{8:8}
result[8] = data[7]{7:0}

索引result (称之为 i )实际上是以 9 为模给出的。因此,数据索引偏移 8 * (i // 9) 。该字节的下半部分由data[...] >> (i + 1)给出。 。上部部分由 data[...] & ((1 << i) - 1) 给出,左移8 - i位。

这使得提出矢量化解决方案变得非常容易:

i = np.arange(result.size)
j = i[:-1]
result[i] = (data[8 * (i // 9) + (i % 9) - 1] & ((1 << i % 9) - 1)) << (8 - i % 9)
result[j] |= (data[8 * (j // 9) + (j % 9)] >> (j % 9 + 1)).astype(np.uint8)

您需要剪辑低部分的索引,因为它可能会超出范围。您不需要剪切高部分,因为 -1 是一个完全有效的索引,并且您不关心它访问哪个元素。当然 numpy 不会让你 OR 或添加 int元素到 uint8数组,所以你必须进行转换。

>>> [bin(x) for x in result]
['0b10011100', '0b1001011', '0b110011', '0b10011001', '0b1000000']

这个解决方案应该可以扩展到任何大小的数组,我编写它是为了让您可以计算出不同的类次组合,而不仅仅是 9 到 8。

关于python - 将 numpy 数组重新排序为新的位长度元素,无需循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69315874/

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