You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Pandas中按Outlook分组统计Play次数并计算香农熵

问题:按Outlook分组统计Play的Yes/No次数并计算香农熵

我有如下Pandas DataFrame数据:

import pandas as pd

data = {
    'Outlook': ['Sunny', 'Sunny', 'Overcast', 'Rainy', 'Rainy', 'Rainy', 'Overcast', 'Sunny', 'Sunny', 'Rainy', 'Sunny', 'Overcast', 'Overcast', 'Rainy'],
    'Temperature': ['Hot', 'Hot', 'Hot', 'Mild', 'Cool', 'Cool', 'Cool', 'Mild', 'Cool', 'Mild', 'Mild', 'Mild', 'Hot', 'Mild'],
    'Humidity': ['High', 'High', 'High', 'High', 'Normal', 'Normal', 'Normal', 'High', 'Normal', 'Normal', 'Normal', 'High', 'Normal', 'High'],
    'Wind': [False, True, False, False, False, True, True, False, False, False, False, True, False, True],
    'Play': ['No', 'No', 'Yes', 'Yes', 'Yes', 'No', 'Yes', 'No', 'Yes', 'Yes', 'Yes', 'Yes', 'Yes', 'No']
}
df = pd.DataFrame(data)

需求:

  • 按Outlook字段的Sunny/Overcast/Rainy分组
  • 统计每组中Play为Yes和No的次数
  • 根据香农熵公式计算每组的熵值:
    $$Entropy = -\left( \frac{yes}{count} \log_2\left(\frac{yes}{count}\right) + \frac{no}{count} \log_2\left(\frac{no}{count}\right) \right)$$
    注:当某类次数为0时,对应项的熵贡献为0(避免log2(0)报错)

期望输出:

Outlook     Yes No  Count of each group Entropy
sunny       2   3   5                   0.971
overcast    4   0   4                   0.000
rainy       3   2   5                   0.971

解决方案

步骤1:分组统计Yes/No次数及组内总数

先用crosstab分组统计Play的次数,再计算每组的总数:

# 分组统计Yes和No的次数
grouped = pd.crosstab(df['Outlook'], df['Play']).reset_index()
# 计算每组的总数
grouped['Count of each group'] = grouped['Yes'] + grouped['No']

步骤2:定义熵计算函数

处理0值的情况,当概率为0时跳过该项的计算:

import numpy as np

def calculate_entropy(row):
    total = row['Count of each group']
    yes_prob = row['Yes'] / total
    no_prob = row['No'] / total
    
    entropy = 0
    if yes_prob > 0:
        entropy -= yes_prob * np.log2(yes_prob)
    if no_prob > 0:
        entropy -= no_prob * np.log2(no_prob)
    return round(entropy, 3)

步骤3:计算熵并整理输出

# 计算熵值
grouped['Entropy'] = grouped.apply(calculate_entropy, axis=1)
# 调整列顺序并格式化输出
result = grouped[['Outlook', 'Yes', 'No', 'Count of each group', 'Entropy']]
# 将Outlook转为小写(匹配期望输出格式)
result['Outlook'] = result['Outlook'].str.lower()

print(result.to_string(index=False))

运行代码后输出:

Outlook  Yes  No  Count of each group  Entropy
  sunny    2    3                    5    0.971
overcast    4    0                    4    0.000
  rainy    3    2                    5    0.971

内容的提问来源于stack exchange,提问作者Ishigami

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 15:47:18