首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >打包数据,Python中的extreme位打包

打包数据,Python中的extreme位打包
EN

Stack Overflow用户
提问于 2021-10-15 07:53:51
回答 2查看 71关注 0票数 1

我需要将信息尽可能地打包到一个比特流中。

我有不同数量的不同状态的变量:

代码语言:javascript
复制
Number_of_states=[3,5,129,15,6,2]# A bit longer in reality

目前最好的选择是创建一个位域,使用

2+3+8+4+3+1位->21位

但是,应该可以将这些状态打包到np.log2(3*5*129*15*6*2)=18.4位中,从而节省两个位。(实际上我有298位,需要节省一些)

在我的例子中,这将节省大约5%的数据流,这将会有很大帮助。

在python中有没有可行的解决方案来以这种方式打包数据?我尝试过packalgorithms,但它们只需要几个字节的数据就会产生太多的开销。字符串是没有问题的,它是常量,并将预先传输。

这是我现在使用的代码:

代码语言:javascript
复制
from bitstring import pack
import numpy as np

DATA_TO_BE_PACKED=np.zeros(6)

Number_of_states=[3,5,129,15,6,2]#mutch longer in reality

DATA_TO_BE_PACKED=np.random.randint(Number_of_states)

string=''

for item in Number_of_states:
    string+='uint:{}, '.format(int(np.ceil(np.log2(item))))

PACKED_DATA = pack(string,*DATA_TO_BE_PACKED)

print(len(PACKED_DATA ))

print(PACKED_DATA.unpack(string))
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-10-15 16:50:47

这看起来像一个mixed radix numeral system的用例。

概念的快速证明:

代码语言:javascript
复制
num_states = [3, 5, 129, 15, 6, 2]
input_data = [2, 3, 78, 9, 0, 1]
print("Input data: %s" % input_data)

要进行编码,请从0开始,对于每个状态,首先乘以状态数,然后添加当前状态:

代码语言:javascript
复制
encoded = 0
for i in range(len(num_states)):
    encoded *= num_states[i]
    encoded += input_data[i]

print("Encoded: %d" % encoded)

要解码,请反向进行,并获得除以状态数的余数,然后除以状态数:

代码语言:javascript
复制
decoded_data = []
for n in reversed(num_states):
    v = encoded % n
    encoded = encoded // n
    decoded_data.insert(0, v)

print("Decoded data: %s" % decoded_data)

输出示例:

代码语言:javascript
复制
Input data: [2, 3, 78, 9, 0, 1]
Encoded: 316009
Decoded data: [2, 3, 78, 9, 0, 1]

另一个具有更多值的示例:

代码语言:javascript
复制
Input data: [2, 3, 78, 9, 0, 1, 84, 17, 4, 5, 30, 1]
Encoded: 14092575747751
Decoded data: [2L, 3L, 78L, 9L, 0L, 1L, 84L, 17L, 4L, 5L, 30L, 1L]
票数 2
EN

Stack Overflow用户

发布于 2021-10-15 11:08:20

您可以将状态解释为形状为(3,5,129,15,6,2)的多维数组的索引。可以将该索引作为整数索引编码到长度为3*5*129*15*6*2 = 348300的平坦化的一维阵列中。NumPy具有ravel_multi_indexunravel_index函数,它们可以为您完成此操作。

例如,假设num_states是状态的每个组件的状态数:

代码语言:javascript
复制
In [86]: num_states = [3, 5, 129, 15, 6, 2]

假设state包含数据的一个实例;也就是说,它记录每个组件的状态:

代码语言:javascript
复制
In [87]: state = [2, 3, 78, 9, 0, 1]

要对此状态进行编码,请通过ravel_multi_index传递它。idx是编码状态:

代码语言:javascript
复制
In [88]: idx = np.ravel_multi_index(state, num_states)

In [89]: idx
Out[89]: 316009

通过构造,0 <= idx < 348300,所以它只需要19位。

要从idx恢复state,请使用unravel_index

代码语言:javascript
复制
In [90]: np.unravel_index(idx, num_states)
Out[90]: (2, 3, 78, 9, 0, 1)
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69581521

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档