- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我试图更好地了解压缩算法(例如 zlib)的输出与理论预期的比较。所以我有几个问题。
(1) 首先,我想检查一下我是否正确计算了压缩率。假设我想压缩 1000 个数组,我可以执行以下操作
# encode the array such that len(s) == 1000 bytes
s = np.ones(1000, dtype='uint8').tostring()
# compress using the python zlib (deflate)
comp_s = zlib.compress(s, 9)
# giving comp_s = 'x\xdacd\x1c\x05\xa3`\x14\x0cw\x00\x00\xa7e\x03\xe9'
comp_ratio = len(comp_s)/len(s)
# giving 17/1000
因此我的第一个问题是:comp_s
编码使其长度对应于字节数?我不太明白这个字符串是如何编码的。如果我这样做 sys.getsizeof(comp_s)
我发现它的大小是 54 字节而不是 17 字节?自 getsizeof
返回 python 对象的大小,因此它肯定高估了字符串的大小,我假设 sys.getsizeof(s) - sys.getsizeof('')
是否正确?是正确的方法吗?它似乎产生与 len()
相同的结果至少。
(2) 压缩序列的大小应大于(或等于)其香农熵。对于以 50:50 概率出现的 1 和 0 的随机二进制序列,每个数字的信息数为 1 位(根据定义 h = - p log p - (1-p)log(1-p)
)。由于真正的随机序列是不可压缩的,如果我生成长度为 n
的随机二进制序列我希望通过添加一个随机数字,得到 n+1
长序列在压缩后平均大 1 位。
当我执行以下操作时
rawsize = range(1, 100000, 1000)
compsize = []
for l in rawsize:
s = np.random.randint(0, 2, l, dtype='uint8').tostring()
comp_s = zlib.compress(s, 9)
# note: I compress again to achieve better compression when l is large
comp_s = zlib.compress(comp_s, 9)
compsize.append(len(comp_s))
如果我绘制 compsize / rawsize
我发现曲线在 0.155
附近接近一个常数值。意思是(如果我解释正确的话)通过增加一位数字,信息量增加了0.155
。 -位。我不明白这一点,因为压缩似乎比理论预期的要好得多。
为了进一步理解这一点,我还比较了 1 和 0 的二进制序列的压缩字符串大小,其中 1 的出现概率为 0<p<1
。 .然后,字符串的压缩大小(每个数字)应该跟踪香农熵并且最大 (=1)
在p=0.5
.我发现压缩字符串大小(每位)的曲线远低于香农熵,如果我将香农熵乘以 0.155
它们大致位于彼此之上。
显然有一些我没有考虑的归一化因素,但我无法弄清楚它的基本原理。我还尝试使用 16
对原始序列进行编码, 32
和 64
位无符号整数,发现比率 compsize / rawsize
大致变成0.176
, 0.2
, 0.23
,因此看起来通过在 1 和 0 的表示中添加一个字节,我们贡献了大约 0.25
。一些额外的信息,这也很好奇。
任何建议都会非常有用!
最佳答案
当调用 np.random.randint(0, 2, l, dtype='uint8').tostring()
时,您获得的不是 0 和 1 的随机序列,而是一个随机序列0 和 1 的 8 位二进制表示序列:10000000
和 00000000
。几乎每 8 位有 1 个是随机的,其他 7 个都是 0。我想最佳比例应该是 1/8 左右,再加上一些开销。
事实上,如果使用 np.random.randint(0, 256, 100000, dtype='uint8').tostring()
,则 comp_ratio 约为 1。
关于python zlib - 压缩字符串的大小与香农熵,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44145560/
在 PyQt 开发中,时常需要对控件的值进行校验,如需要校验 QCheckBox 是否被选中, QLabel 是否校验值是否为空等等。在复杂的业务场景下,这类控件如果数量很多,逐个校验就
我是一名优秀的程序员,十分优秀!