简体   繁体   English

Numpy 将位打包成 32 位小端值

[英]Numpy pack bits into 32-bit little-endian values

Numpy provides packbits function to convert from values to individual bits. Numpy 提供包位 function以将值转换为单个位。 With bitorder='little' I can read them in C as uint8_t values without issues.使用bitorder='little'我可以在 C 中将它们读取为 uint8_t 值而不会出现问题。 However, I would like to read them as uint32_t values.但是,我想将它们读取为 uint32_t 值。 This means that I have to reverse the order of each 4 bytes.这意味着我必须颠倒每 4 个字节的顺序。 I tried to use我试着用

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)

but have the following error:但出现以下错误:

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.

I have 50 bits in the input.我在输入中有 50 位。 The first chunk of 32 bits written in the little-endian format (earliest input bit is the least significant bit) are 0b10101001101011001101001010101101 = 2846675629 , the second is 0b100111001101011001 = 160601 .以 little-endian 格式写入的第一个 32 位块(最早的输入位是最低有效位)是0b10101001101011001101001010101101 = 2846675629 ,第二个是0b100111001101011001 = 160601 So the expected output is所以预期的 output 是

[2846675629 160601]

You can't use array.dtype = np.uint32 as you did, because numpy arrays have to be consecutive in memory.您不能像以前那样使用array.dtype = np.uint32 ,因为 numpy arrays 必须在 memory 中连续。

Instead, you can create a new array of the new type.相反,您可以创建新类型的新数组。

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)

My first answer fixes the exception.我的第一个答案修复了异常。

This answer, relies on this and this这个答案,依赖于这个这个

  • Pad the array from the right to the nearest power of 2将数组从右边填充到最接近的 2 次幂
  • Reshape to have some arrays, each array of size 32重塑有一些 arrays,每个数组的大小为 32
  • Pack bits PER ARRAY and only then view as unit32 .按数组打包位,然后仅将其视为unit32
import numpy as np
import math


# https://stackoverflow.com/questions/49791312/numpy-packbits-pack-to-uint16-array
# https://stackoverflow.com/questions/36534035/pad-0s-of-numpy-array-to-nearest-power-of-two/36534077


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)

output: output:

[2846675629 160601] [2846675629 160601]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM