基于Pandas列表列构建堆叠表统计学生互见次数的问题
解决Pandas统计学生窗口观测次数的堆叠表问题
问题背景
原始DataFrame代码:
import pandas as pd df = pd.DataFrame( { "Student": ['Daphne','Scooby','Daphne','Shaggy','Fred','Daphne'], "window": [['Fred'],['Daphne'], [''], ['Daphne'],['Velma','Scrappy'],['Velma','Fred']] } )
数据展示:
Student window 0 Daphne [Fred] 1 Scooby [Daphne] 2 Daphne [] 3 Shaggy [Daphne] 4 Fred [Velma, Scrappy] 5 Daphne [Velma, Fred]
需求:生成堆叠表,统计每位学生在窗口中看到其他学生的次数,预期结果:
Daphne Fred Scrappy Velma Daphne 0 2 0 1 Fred 0 0 1 1 Scrappy 0 0 0 0 Velma 0 0 0 0
原代码的问题分析
你之前的代码逻辑完全偏离需求:
- 丢失关联信息:
df["window"].apply(pd.Series).stack()仅处理了window列,丢掉了和Student列的对应关系,后续无法将观测次数归属到具体学生。 - 错误的计算逻辑:
dfd.T.dot(dfd)计算的是不同学生在窗口中的共现次数(比如两个学生同时出现在同一个窗口的次数),而非每个学生看到其他学生的次数。 - 空值处理不当:
dfd.drop(0)和del dfd['']没有从根源过滤空窗口,反而破坏了数据结构,无法解决问题。
正确解决方案
步骤1:展开窗口并保留学生关联
先将window列的列表展开为行,同时保留对应的Student信息,并过滤空值:
# 展开window列表,每个元素对应一行,保留Student expanded_df = df.explode('window') # 过滤空的窗口值 expanded_df = expanded_df[expanded_df['window'] != '']
步骤2:统计观测次数
使用pd.crosstab直接统计每个Student看到window中各学生的次数:
count_table = pd.crosstab(expanded_df['Student'], expanded_df['window'])
此时得到的结果:
window Daphne Fred Scrappy Velma Student Daphne 0 2 0 1 Fred 0 0 1 1 Shaggy 1 0 0 0 Scooby 1 0 0 0
步骤3:调整结果匹配预期
如果只需要保留窗口中出现过的学生作为行(和预期一致),重新索引并填充缺失值:
# 获取所有在window中出现过的学生 window_students = pd.unique(expanded_df['window']) # 重新索引,缺失行填充0 final_result = count_table.reindex(window_students, fill_value=0)
最终结果完全符合预期:
Daphne Fred Scrappy Velma Daphne 0 2 0 1 Fred 0 0 1 1 Scrappy 0 0 0 0 Velma 0 0 0 0
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

