如何在Python Pandas中通过循环按两列组合拆分DataFrame
处理大型DataFrame的分组聚合需求
我在Jupyter Notebook里有一个超500万行、5列的大型DataFrame,其中Name列有20个唯一值,lot列有10个唯一值,总共200种唯一组合。需要按这两列的组合拆分DataFrame,计算指定列的均值、求和后,汇总成一个200行的最终DataFrame(每行对应一种组合)。
示例数据
原始DataFrame(dfhuge)示例:
index Name lot col3 col4 col5 123 delta 1 786 10 1 657 delta 2 787 11 2 567 delta 2 777 13 4 456 bravo 3 775 12 3 789 bravo 3 772 14 5
手动处理单组的代码示例:
df1outof6 = dfhuge.loc[(dfhuge["Name"] == "delta") & (dfhuge["lot"] == 2)] mean = df1outof6["col4"].mean() sum_val = df1outof6["col5"].sum()
最终需求格式
最终输出的finaldf需要包含所有200种组合,无数据的组合填充0:
finaldf newcol col4mean col5sum combination1(delta and 2) 12 6 combination2(delta and 1) 10 1 combination3(delta and 3) 0 0 combination4(bravo and 1) 0 0 combination5(bravo and 2) 0 0 combination6(bravo and 3) 13 8
解决方案
方法1:用groupby+聚合(推荐,大数据场景高效)
直接使用pandas内置的分组聚合功能,底层优化过的逻辑比循环快数倍,适合处理500万行的数据集:
import pandas as pd # 1. 按Name和lot分组,计算指定列的统计值 grouped = dfhuge.groupby(["Name", "lot"]).agg( col4mean=("col4", "mean"), col5sum=("col5", "sum") ).reset_index() # 2. 生成所有可能的Name+lot组合(包含无数据的空组合) all_names = dfhuge["Name"].unique() all_lots = dfhuge["lot"].unique() all_combinations = pd.MultiIndex.from_product([all_names, all_lots], names=["Name", "lot"]) # 3. 对齐分组结果与全组合,缺失值填充0 finaldf = grouped.set_index(["Name", "lot"]).reindex(all_combinations, fill_value=0).reset_index() # 4. 生成指定格式的newcol列 finaldf["newcol"] = [f"combination{i+1}({row['Name']} and {row['lot']})" for i, row in finaldf.iterrows()] # 5. 调整列顺序并设置索引(按需选择) finaldf = finaldf[["newcol", "col4mean", "col5sum"]].set_index("newcol")
方法2:循环处理所有组合(不推荐,大数据下效率低)
如果必须用循环实现,可按以下步骤操作:
import pandas as pd # 1. 获取所有唯一的Name和lot值 all_names = dfhuge["Name"].unique() all_lots = dfhuge["lot"].unique() # 2. 初始化结果存储列表 results = [] # 3. 遍历所有组合并计算 for idx, name in enumerate(all_names): for lot in all_lots: # 筛选当前组合的数据 subset = dfhuge.loc[(dfhuge["Name"] == name) & (dfhuge["lot"] == lot)] # 空数据集时返回0,否则计算统计值 col4_mean = subset["col4"].mean() if not subset.empty else 0 col5_sum = subset["col5"].sum() if not subset.empty else 0 # 组合结果字典并添加到列表 combo_num = idx * len(all_lots) + (list(all_lots).index(lot) + 1) results.append({ "newcol": f"combination{combo_num}({name} and {lot})", "col4mean": col4_mean, "col5sum": col5_sum }) # 4. 转换为最终DataFrame finaldf = pd.DataFrame(results).set_index("newcol")
内容的提问来源于stack exchange,提问作者AAA
相关产品推荐
相关产品推荐

