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]
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)
本回答,依赖
- 将数组从右边填充到最接近的 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]