
本文介绍两种高效方法:使用 pivot_table 或 value_counts().unstack(),将用户-行为原始数据转换为以用户为行、行为为列的频数矩阵,并自动填充缺失值为 0。
本文介绍两种高效方法:使用 `pivot_table` 或 `value_counts().unstack()`,将用户-行为原始数据转换为以用户为行、行为为列的频数矩阵,并自动填充缺失值为 0。
在数据分析中,常需将“长格式”用户行为日志(如用户访问页面记录)转换为“宽格式”的交叉频数表,便于后续分析或可视化。给定如下 DataFrame:
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)
目标是得到每个 User 对应各 Action(如 Page1/2/3)的计数,缺失组合补 0,结果形如:
User Page1 Page2 Page3 0 AA 2 1 0 1 BB 0 1 1 2 CC 0 0 2
✅ 推荐方案一:pivot_table(语义清晰,灵活可控)
result = df.pivot_table(
index="User",
columns="Action",
aggfunc=len, # 每组计数
fill_value=0 # 空单元格填 0
).reset_index()
result.columns.name = None # 可选:清除列名层级中的 'Action'
print(result)
?
pivot_table显式指定索引、列和聚合逻辑,适合需要扩展(如加权重、多指标)的场景。
✅ 推荐方案二:value_counts().unstack()(简洁高效,专用于频数统计)
result = df.value_counts().unstack(fill_value=0).reset_index() result.columns.name = None print(result)
⚠️ 注意:
df.value_counts()默认按所有列组合计数,返回Series;unstack()将Action自动提升为列,fill_value=0补零。此法代码极简,性能优异,但仅适用于纯频数统计。
? 关键细节与注意事项
-
列顺序:
unstack()生成的列顺序由Action值的唯一值排序决定(字典序),若需自定义顺序,可在unstack()后用reindex(columns=[...])调整; -
索引重置:两种方法均需
.reset_index()将User从索引转为普通列,否则User会作为Index不参与后续操作; -
避免歧义:若原始数据含重复完全相同的行(如
(AA, Page1)出现两次且需视为两条独立记录),value_counts()默认计数已包含重复,无需额外处理;若需去重统计,应先drop_duplicates(); -
扩展性提示:如需同时统计多个指标(如访问时长均值、最大值),
pivot_table支持aggfunc={'duration': ['mean', 'max']},而value_counts不适用。
综上,对标准频数交叉表任务,优先推荐 df.value_counts().unstack(fill_value=0) —— 简洁、快速、可读性强;若需更高灵活性或兼容复杂聚合逻辑,则选用 pivot_table。










