【问题标题】:How to calculate entropy from frequency table?如何从频率表计算熵?
【发布时间】:2019-09-23 12:17:47
【问题描述】:

我有一堆名字(> 1000 万)及其相关数量的数据。

import pandas as pd
import numpy as np


data = {
    "Name": ['Sara', 'John', 'Mark', 'Peter', 'Kate'],
    "Count": [20, 10, 5, 2, 5],
}

df = pd.DataFrame(data)
print(df)
    Name  Count
0   Sara     20
1   John     10
2   Mark      5
3  Peter      2
4   Kate      5

我想计算Count 列的熵,而不将数据扩展为[Sara, Sara, Sara,...,Kate, Kate, Kate],因为对此有太多的观察。

如何在不扩展数据的情况下计算 Count 的熵?

【问题讨论】:

  • 定义熵。
  • 通过将计数转换为 bin 概率(每个计数除以总计数)并求和 -pi*log(pi) (请参阅stackoverflow.com/questions/15450192/…),不容易根据计数计算熵跨度>

标签: python pandas numpy dataframe entropy


【解决方案1】:

假设数据框包含每个名称的值计数,您可以直接将计数的Series 提供给scipy.stats.entropy

from scipy.stats import entropy

entropy(df.set_index('Name').squeeze())
# 1.3466893828909594

正如@nils 提到的,如果你想要的是二进制熵,你可以设置base=2

【讨论】:

  • OP 最有可能在寻找香农熵,因此您需要设置 kwarg base=2
【解决方案2】:

如果你想计算德香农的熵H = -Sum[ P(xi) * log2( P(xi)) ]

import pandas as pd
import numpy as np
import math


data = {
    "Name": ['Sara', 'John', 'Mark', 'Peter', 'Kate'],
    "Count": [20, 10, 5, 2, 5],
}

df = pd.DataFrame(data)
df['prob'] = df['Count']/df['Count'].sum()
df['log'] = df.apply(lambda x: math.log(x['prob'],2),axis=1)
df['prod'] = df['prob']*df['log']

print('Entropy: ', -df['prod'].sum())

【讨论】:

  • 不需要apply()math.log(),而是可以全部矢量化。
猜你喜欢
  • 2023-04-05
  • 2021-10-15
  • 2016-12-04
  • 1970-01-01
  • 1970-01-01
  • 2020-05-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多