concat横向合并按索引对齐而非列名,需先统一索引或改用join;纵向合并易现重复索引,应设ignore_index=true或加源标识;列类型不一致会导致object型及运算错误,须预清洗;多df合并性能差,应预处理后一次性concat并设sort=false。

concat横向合并时列名对不齐,数据错位怎么办
横向合并(axis=1)本质是按索引对齐,不是按列名对齐。哪怕两个 DataFrame 都有 "id" 和 "name" 列,只要索引不一致,pd.concat([df1, df2], axis=1) 就会把不同行的数据强行并排,导致“张三”的年龄配上“李四”的城市。
解决方法只有两个:
- 先统一索引:
df1 = df1.set_index("id"),df2 = df2.set_index("id"),再concat; - 或改用
join:df1.join(df2, on="id", rsuffix="_right"),更安全可控; - 别依赖
concat做“按列名关联”,它压根不看列名是否重复或语义是否匹配。
纵向合并(axis=0)后出现重复索引,groupby出错
pd.concat([df_a, df_b], axis=0) 默认保留原始索引,比如两个 DataFrame 各自索引都是 [0, 1, 2],合并后就变成 [0,1,2,0,1,2]。后续调用 df.groupby("category").size() 不报错,但 df.loc[0] 会返回两行——这不是 bug,是设计如此。
实际处理建议:
- 加
ignore_index=True:重置为连续整数索引; - 若需保留原始标识,提前加前缀:
df_a = df_a.assign(source="A"),再合并; - 检查索引唯一性:
df.index.is_unique,比事后调试快得多。
列名相同但类型不同(如 str vs int),concat后变成object
比如 df1["score"] 是 int64,df2["score"] 是 string(含空值或"missing"),concat 后该列自动转成 object,后续 .sum() 直接报 TypeError: unsupported operand type(s) for +: 'int' and 'str'。
必须在合并前清洗:
- 统一数值列:
pd.to_numeric(df["score"], errors="coerce")把非法值转NaN; - 避免用字符串存数字,尤其从 Excel 或 CSV 读入时,显式指定
dtype; - 合并后快速验证:
df.dtypes和df["score"].apply(type).unique()比对。
concat多个DataFrame时性能突然变慢
写成 pd.concat([df1, df2, df3, df4, df5]) 看似简洁,但 pandas 内部是两两合并的,时间复杂度接近 O(n²)。10 个 10 万行的 DataFrame 合并可能比循环 append 还慢(虽然 append 已弃用)。
高效做法只有一条:
- 用列表推导式预处理好所有 DataFrame,确保列顺序、类型、索引一致;
- 一次性传入列表:
pd.concat(all_dfs, ignore_index=True, sort=False); - 禁用自动排序:
sort=False避免内部按列名重排,尤其列多时提速明显; - 小数据无所谓,上万行以上务必测
%timeit。
列名相同不等于结构兼容——类型、空值策略、索引逻辑,三个地方错一个,concat 就会默默给你埋雷。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











