如何将6个同列pandas DataFrame合并为带分组频次统计的自定义格式表
目标格式实现方案
核心实现逻辑
替代逐行嵌套遍历的低效逻辑,用pandas内置的纵向合并、分组、透视功能完成统计,从根源上避免拼接乱值、分组粒度不对的问题。
分步操作
1. 预处理所有源表
统一修正字段名(比如把原代码里的session.id改成统一的session_id),生成拼接字段player_info,标记每个源表的来源,把6个源表合并成一张总表:
import pandas as pd import numpy as np # df_list 为现有代码中存储6个源Excel对应DataFrame的列表 # 若之前存的是文件路径,可先统一读成DataFrame: # df_list = [pd.read_excel(path) for path in df_path_list] processed_dfs = [] for idx, df in enumerate(df_list): # 修正字段名不匹配问题 df = df.rename(columns={"session.id": "session_id"}) # 拼接生成player_info字段 df["player_info"] = df["gersey_color"].astype(str) + df["player_id"].astype(str) # 标记当前数据来自第几个源表 df["source_tag"] = f"df{idx+1}" processed_dfs.append(df) # 纵向合并所有源表 all_records = pd.concat(processed_dfs, ignore_index=True)
2. 分组统计各源表的出现频次
按照session_id、player_info、timestamp三个维度分组,统计每个源表的条目数,通过透视表生成df1~df6的计数列:
# 基础分组计数:每个(会话, 球员, 时间, 来源表)组合的条目数 count_result = all_records.groupby( ["session_id", "player_info", "timestamp", "source_tag"] ).size().reset_index(name="count") # 把长表透成目标宽表 pivot_result = count_result.pivot( index=["session_id", "player_info", "timestamp"], columns="source_tag", values="count" ).reset_index() # 补全所有df1~df6列,缺失值填充为0 target_df_cols = [f"df{i+1}" for i in range(len(df_list))] for col in target_df_cols: if col not in pivot_result.columns: pivot_result[col] = 0 pivot_result = pivot_result.fillna(0).astype({col: int for col in target_df_cols}) # 计算每个球员分组的总出现次数 pivot_result["total_occurance"] = pivot_result[target_df_cols].sum(axis=1)
3. 调整单元格填充样式匹配目标输出
同一会话、同一时间戳下的多行球员记录,仅在分组首行填充session_id和timestamp,其余同组行留空:
# 按会话、时间排序,保证同组记录连续排列 pivot_result = pivot_result.sort_values( ["session_id", "timestamp", "player_info"] ).reset_index(drop=True) # 同组内非首行的session_id、timestamp置空 for col in ["session_id", "timestamp"]: pivot_result[col] = pivot_result[col].where( pivot_result[col] != pivot_result[col].shift() ) # 调整列顺序匹配目标格式 final_columns = ["session_id", "player_info"] + target_df_cols + ["total_occurance", "timestamp"] final_df = pivot_result[final_columns]
现有代码的问题修正点
- 把之前df1~df6列存拼接字符串的逻辑,改成按
player_info分组的计数结果,解决多值挤在一个单元格的问题 - 不再按timestamp单维度遍历,而是按
session_id + player_info + timestamp的组合粒度分组,把同会话下的不同球员拆成独立行 - 避免逐行重复读取Excel文件,一次性加载所有源表完成统计,大幅提升运行效率
内容的提问来源于stack exchange,提问作者Tokai
相关产品推荐
相关产品推荐

