
本文介绍如何使用 pandas 将宽表形式的用户行为数据(如 user-action)高效转换为交叉频数矩阵,即每个用户对应各页面的计数,支持自动补零、列名对齐与索引重置。
本文介绍如何使用 pandas 将宽表形式的用户行为数据(如 user-action)高效转换为交叉频数矩阵,即每个用户对应各页面的计数,支持自动补零、列名对齐与索引重置。
在数据分析中,常需将长格式的行为日志(如用户点击页面记录)转化为便于可视化或建模的宽格式汇总表。例如,给定包含 User 和 Action 两列的 DataFrame,目标是生成一个以用户为行、以不同 Action 值(如 Page1/ Page2/ Page3)为列、单元格值为对应组合出现频次的二维计数表,并确保缺失组合填充为 0。
推荐两种简洁高效的实现方式:
✅ 方法一:pd.crosstab() —— 最直观、专为此类任务设计
import pandas as pd
data = {
"User": ["AA", "AA", "AA", "BB", "BB", "CC", "CC"],
"Action": ["Page1", "Page1", "Page2", "Page2", "Page3", "Page3", "Page3"],
}
df = pd.DataFrame(data)
# 生成交叉频数表,自动填充 0,且 User 作为索引(可选 reset_index)
result = pd.crosstab(df['User'], df['Action']).reset_index()
print(result)
输出:
Action User Page1 Page2 Page3 0 AA 2 1 0 1 BB 0 1 1 2 CC 0 0 2
✅ 方法二:df.value_counts().unstack() —— 链式操作,语义清晰
result = df.value_counts(['User', 'Action']).unstack(fill_value=0).reset_index() result.columns.name = None # 清除列名层级中的 'Action' print(result)
⚠️ 注意:
unstack()默认会保留多级列名(如Action作为顶层),调用.columns.name = None可去除冗余标签,使列结构更干净。
✅ 方法三:df.pivot_table() —— 灵活可控(适合扩展聚合逻辑)
result = df.pivot_table(
index='User',
columns='Action',
aggfunc='size', # 等价于 len,但更明确表示计数
fill_value=0
).reset_index()
? 提示:
aggfunc='size'比len更安全,避免空组引发异常;若后续需加权统计,此处还可替换为aggfunc='sum'等。
? 关键注意事项
- 所有方法均自动识别并覆盖所有唯一
Action值作为列名,无需手动指定; -
fill_value=0是关键参数,确保未发生的行为组合显示为 0 而非NaN; - 若原始数据含重复行且需去重统计,请先执行
df.drop_duplicates(); - 输出 DataFrame 的列顺序按
Action字典序排列,如需自定义顺序,可在crosstab后使用reindex(columns=['Page1','Page2','Page3'])。
综上,pd.crosstab() 是此类“双维度频数统计”任务的首选方案——代码简短、语义明确、性能优异,且天然适配后续绘图(如 seaborn.heatmap)或机器学习特征工程场景。










