Numpy 将位打包成 32 位小端值

Numpy pack bits into 32-bit little-endian values

Numpy 提供 packbits 函数将值转换为单个位。使用 bitorder='little' 我可以在 C 中将它们读取为 uint8_t 值而不会出现问题。但是,我想将它们读取为 uint32_t 值。这意味着我必须颠倒每 4 个字节的顺序。 我尝试使用

import numpy as np

array = np.array([1,0,1,1,0,1,0,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,1,1,0,0,1,0,1,0,1, 
   1,0,0,1,1,0,1,0,1,1,0,0,1,1,1,0,0,1])
array = np.packbits(array, bitorder='little')
array.dtype = np.uint32
array.byteswap(inplace=True)

print(array)

但出现以下错误:

Traceback (most recent call last):
  File "sample.py", line 5, in <module>
    array.dtype = np.uint32
ValueError: When changing to a larger dtype, its size must be a divisor of the total size in bytes of the last axis of the array.

我的输入有 50 位。以小端格式写入的第一个 32 位块(最早的输入位是最低有效位)是 0b10101001101011001101001010101101 = 2846675629,第二个是 0b100111001101011001 = 160601。所以预期的输出是

[2846675629 160601]

你不能像以前那样使用array.dtype = np.uint32,因为numpy数组在内存中必须是连续的。

相反,您可以创建一个新类型的新数组。

import numpy as np

array = np.array([1,0,1,1,0,1,0,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,1,1,0,0,1,0,1,0,1,1,0,0,1,1,0,1,0,1,1,0,0,1,1,1,0,0,1])
array = np.packbits(array, bitorder='little')
array = np.array(array, dtype=np.uint32)
array.byteswap(inplace=True)

print(array)

修复了异常。

本回答,依赖 and

  • 将数组从右边填充到最接近的 2 的幂
  • 重构为一些数组,每个数组的大小为 32
  • 打包每个数组的位,然后才查看为 unit32
import numpy as np
import math


# 
# 


def next_power_of_2(number):
    # Returns next power of two following 'number'
    return 2**math.ceil(math.log(number, 2))


a = np.array([
    1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1,
    1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1
])

# a = np.array([
#     0 for _ in range(31)
# ] + [1])
padding_size = next_power_of_2(len(a)) - len(a)
b = np.concatenate([a, np.zeros(padding_size)])
c = b.reshape((-1, 32)).astype(np.uint8)
d = np.packbits(c, bitorder='little').view(np.uint32)

print(d)

输出:

[2846675629 160601]