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,是设计如此。
实际处理建议:
立即学习“Python免费学习笔记(深入)”;
加
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 就会默默给你埋雷。

