【问题标题】:How to compute Shannon entropy of Information from a Pandas Dataframe?如何从 Pandas 数据框中计算信息的香农熵?
【发布时间】:2018-11-06 17:51:48
【问题描述】:

我有一个数据框 df,其中包含从个人 Name_Give 到另一个 Name_Receive 的交易信息,如下所示:

df
    Name_Give    Name_Receive   Amount
0    John           Tom          300
1    Eva            Tom          700
2    Sarah          Tom          100
3    John           Tom          200
4    Tom            Eva          700
5    John           Eva          300
6    Carl           Eva          250

对于每个Name_Receive j,我想将香农熵计算为S_j = -sum_i p_i \log p_i,其中p_i 是金额除以用户j 金额的总和

S_Tom = - (300/1300 * np.log(300/1300) + 700/1300 * np.log(700/1300) + 100/1300 * np.log(100/1300) + 200/1300 * np.log(200/1300))

S_Eva = - (700/1250 * np.log(700/1250) + 300/1250 * np.log(300/1250) + 250/1250 * np.log(250/1250)

S_Tom = 1.157
S_Eva = 0.99

我想要数据框df1,如下所示

df1
     Name     Entropy
0    Tom      1.157
1    Eva      0.99

【问题讨论】:

    标签: python pandas entropy


    【解决方案1】:

    使用groupbytransfrom 获得每个组的总和,然后将Amount 列值除以每个组的总和并计算值:

    g_sum = df.groupby('Name_Receive')['Amount'].transform('sum')
    values = df['Amount']/g_sum
    df['Entropy'] = -(values*np.log(values))
    
    df1 = df.groupby('Name_Receive',as_index=False,sort=False)['Entropy'].sum()
    
    print(df1)
      Name_Receive   Entropy
    0          Tom  1.156988
    1          Eva  0.989094
    

    如果值包含 0,则在 groupby 之后的末尾使用:

    df1['Entropy'] = df1['Entropy'].fillna(0)
    

    由于0*np.log(0) 给了nan 使其成为0 使用fillna

    【讨论】:

    • 我认为这是一个很好的解决方案,但仅假设您在“金额”列中没有 0 值。 >>> np.log([1, np.e, np.e**2, 0]) 将导致:array([ 0., 1., 2., -Inf]) 在计算熵时,应跳过零值(或求和为零)
    • @Oleg 当您将0*np.log(0) 相乘时,您会得到nan,而不是Inf。这可以使用fillna(0) 轻松填充。在写答案时,我只考虑了样本数据,没有考虑任何其他类似的限制。
    • 对于示例数据,它会起作用,但我个人来找它为我的案例寻找解决方案。也许您应该考虑为 0 值添加一个选项以涵盖所有情况。您的建议应该可行,我认为另一种方法是使用 import scipy.stats as st df['Entropy'] = st.entropy(values)
    • @Oleg 我测试了st.entropy,即使这给出了nan 并更新了0 案例的答案。
    【解决方案2】:

    你也可以应用 scipy 的熵函数

    from scipy.stats import entropy
    E = df.groupby('Name_Receive')['Amount'].apply(lambda x : entropy(x.value_counts(), base=2)).reset_index()
    

    【讨论】:

      猜你喜欢
      • 2014-03-31
      • 1970-01-01
      • 2014-07-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-31
      • 2021-12-02
      • 1970-01-01
      相关资源
      最近更新 更多