我正在尝试计算可执行文件的字节熵。在将直方图作为数组后,我首先使用for循环进行计算。然后,我尝试使用functools.reduce进行固定。有趣的是,我从相同的数组和相同的函数中获得了不同的结果,并且我想了解为什么。
我将其简化为一个简单的循环和两行代码块,但是,我不明白为什么其中之一是错误的。我比较了for循环中列表“ prob”和“ prob”的所有元素,所有值都相同。
sudo iotedge logs <yourModuleName>
AND
sudo iotedge logs <yourModuleName> -f --tail 100
其中一个捐献0.813826598594107,另一个捐献给0.8605594205272858。 “ hist”是一个numpy.ndarray。
答案 0 :(得分:4)
您的初始值是不同的。
在循环版本中,您首先应用calc_entropy(0, prob[0])
,但减少后,您的第一个应用是calc_entropy(prob[0], prob[1])
。您可以通过使用初始值reduce
调用reduce(calc_entropy, prob, 0)
来更改它。
答案 1 :(得分:2)
问题是初始值,就像@YSelf在他的答案中指出的那样。
这是一个示范:
import functools
import math
import numpy as np
calc_entropy = lambda e, p: e - p*math.log(p, 256) if (p != .0) else e
def f1a(hist, bytes_len):
prob = hist / bytes_len
e = functools.reduce(calc_entropy, prob) # no initial value
return e
def f1b(hist, bytes_len):
prob = hist / bytes_len
e = functools.reduce(calc_entropy, prob, 0.0) # with initial value
return e
def f2(hist, bytes_len):
e = 0.0
for freq in hist:
prob = freq / bytes_len
e = calc_entropy(e, prob)
return e
一些测试(我只显示一个测试,但是我用不同的数字进行了几个测试,所有测试的结论都如下):
>>> b = 5
>>> h = np.random.rand(10)
>>> h
[0.68968912 0.37621079 0.76577699 0.06287911 0.49159805 0.63960027
0.50323918 0.56442714 0.28445216 0.03391277]
>>> f1a(h, b)
0.4449530941371813
>>> f1b(h, b)
0.3562920060014537
>>> f2(h, b)
0.3562920060014537
请注意f1b()
和f2()
的结果如何相等,但与f1a()
不同。