11 비트 정수의 압축 된 스트림을 나타내는 bytes 객체 또는 bytearray 객체가 있습니다. (편집 : 스트림은 패딩없이 11 비트 빅 엔디안 정수입니다.)16 비트 정수의 배열에 11 비트 정수를 포함하는 bytearray 캐스팅
이것을 16 비트 정수 스트림으로 복사하는 효율적인 방법이 있습니까? 또는 다른 정수 유형?
나는 ctypes가 비트 필드를 지원한다는 것을 알고 있지만 이것이 나를 전혀 도움이되는지 확신 할 수 없다.
다른 용도로 이미 비트 피딩을하는 표준 라이브러리의 일부를 "남용"할 수 있습니까?
cython에 의존해야한다면 가변 비트 길이를 처리 할 수있는 좋은 구현이 있습니까? 나는. 11 비트 입력뿐만 아니라 12, 13 등을 위해?
편집 : PM2 링의 답변에 따라 순수 파이썬 솔루션
def unpackIntegers(data, num_points, bit_len):
"""Unpacks an array of integers of arbitrary bit-length into a
system-word aligned array of integers"""
# TODO: deal with native integer types separately for speedups
mask = (1 << bit_len) - 1
unpacked_bit_len = 2 ** ceil(log(bit_len, 2))
unpacked_byte_len = ceil(unpacked_bit_len/8)
unpacked_array = bytearray(num_points * unpacked_byte_len)
unpacked = memoryview(unpacked_array).cast(
FORMAT_CODES[unpacked_byte_len])
num_blocks = num_points // 8
# Note: zipping generators is faster than calculating offsets
# from a block count
for idx1_start, idx1_stop, idx2_start, idx2_stop in zip(
range(0, num_blocks*bit_len, bit_len),
range(bit_len, (num_blocks+1)*bit_len, bit_len),
range(7, num_points, 8),
range(-1, num_points-8, 8),
):
n = int.from_bytes(data[idx1_start:idx1_stop], 'big')
for i in range(idx2_start, idx2_stop, -1):
unpacked[i] = n & mask
n >>= bit_len
# process left-over part (missing from PM2 Ring's answer)
else:
points_left = num_points % 8
bits_left = points_left * bit_len
bytes_left = len(data)-num_blocks*bit_len
num_unused_bits = bytes_left * 8 - bits_left
n = int.from_bytes(data[num_blocks*bit_len:], 'big')
n >>= num_unused_bits
for i in range(num_points-1, num_points-points_left-1, -1):
unpacked[i] = n & mask
n >>= bit_len
return unpacked