本文详解如何在循环中动态构建并合并多个长度不同的 DataFrame,推荐使用 pd.concat() 替代低效的逐列赋值或 append()(已弃用),确保数据结构正确、性能稳定。
本文详解如何在循环中动态构建并合并多个长度不同的 dataframe,推荐使用 `pd.concat()` 替代低效的逐列赋值或 `append()`(已弃用),确保数据结构正确、性能稳定。
在实际数据分析中,常需对分组数据(如按 col_1 和 col_2 的组合)分别建模,并将原始值与预测结果统一汇总。但直接向空 DataFrame 逐列赋值(如 table['col_x'] = [x]*len(filtered_df))会引发索引错位、长度不匹配或覆盖写入等问题——尤其当各组样本数不同(即 len(filtered_df) 每次变化)时,Pandas 无法自动对齐。
✅ 正确做法:每次循环生成一个独立的临时 DataFrame,最后一次性合并。避免修改共享 DataFrame,杜绝索引混乱。
以下为优化后的完整实现:
import pandas as pd
# 初始化存储列表(比反复 concat 更高效)
dfs_to_concat = []
for x in ['a', 'b', 'c']:
for y in ['d', 'e', 'f']:
filtered_df = df[(df[col_1] == x) & (df[col_2] == y)]
s1 = filtered_df[col_3]
# 假设 s2 是与 s1 等长的预测 Series(例如 linear_model.predict(filtered_df[features]))
# ✅ 构建当前组的 DataFrame(自动对齐索引)
temp_df = pd.DataFrame({
'col_x': [x] * len(s1),
'col_y': [y] * len(s1),
'col_3': s1.values, # 显式转为数组,避免索引继承问题
'predict': s2.values # 同理,确保长度一致且无索引干扰
})
dfs_to_concat.append(temp_df)
# ✅ 一次性合并所有结果(推荐 axis=0,默认纵向堆叠)
result_table = pd.concat(dfs_to_concat, ignore_index=True)⚠️ 关键注意事项:
立即学习“Python免费学习笔记(深入)”;
- 不要使用 DataFrame.append():自 Pandas 1.4.0 起已完全弃用,且效率远低于 pd.concat();
- 避免在循环内重复 pd.concat():每次调用都会创建新对象,时间复杂度 O(n²);应先收集再合并;
- 显式使用 .values 提取 NumPy 数组:防止 Series 索引与目标 DataFrame 索引不匹配导致填充 NaN;
- ignore_index=True:重置最终索引,避免重复或跳跃索引;
- 务必确保 s1 与 s2 长度严格相等:可在循环内添加断言校验 assert len(s1) == len(s2),提升鲁棒性。
? 进阶提示:若数据量极大,可考虑使用 pd.concat(..., copy=False)(Pandas ≥ 2.2)减少内存拷贝;对于更复杂的分组建模流程,建议封装为函数并结合 df.groupby([...]).apply(...) 实现向量化处理。
通过该模式,无论每组数据长度如何变化,最终 result_table 都能准确、高效、可复现地整合全部结果。


















