df1 + df2 出现大量 nan 是因为 pandas 默认按索引(行名+列名)严格对齐而非位置;不匹配处填 nan;可改用 .values 相加、add(fill_value=0) 或 align() 预对齐。

为什么 df1 + df2 结果里很多 NaN?
因为 Pandas 在算术运算时默认按索引(行名 + 列名)严格对齐,不是按位置。两个 DataFrame 的索引不完全重合,缺失位置就填 NaN。
- 常见错误现象:
df_a + df_b后大量NaN,但数据明明“看起来一样多” - 本质是:Pandas 先匹配
df_a.index == df_b.index和df_a.columns == df_b.columns,再计算;不匹配的单元格不参与运算,直接返回NaN - 典型场景:合并不同来源的月度销售表(索引是日期),但某个月一方缺数据、另一方有空值,或列顺序不一致
- 示例:
pd.DataFrame({'A': [1,2]}, index=[0,1]) + pd.DataFrame({'A': [10]}, index=[1])→ 第 0 行A是NaN,只第 1 行算出12
想按位置相加,而不是按索引对齐,怎么办?
用 .values 或 numpy 底层数组操作,绕过 Pandas 的自动对齐逻辑。
图片提示词生成器?不止如此。 马甲系统 —— 把脑海中的画面,翻译成AI能理解的专业表达。 用得越多,它越懂你:首次需要多问几句确认方向,用久了几乎一说就懂。 用得越多,它越快:缓存机制让后续对话越来越省。 RAG进化:成功案例持续入库,越跑越聪明。 输入「新手指南」查看完整功能介绍
-
df1.values + df2.values返回numpy.ndarray,形状必须一致,否则报ValueError: operands could not be broadcast together - 如果只要结果是 DataFrame,得手动重建:
pd.DataFrame(df1.values + df2.values, index=df1.index, columns=df1.columns) - 注意:这会丢弃索引语义(比如时间对齐失效),且不检查 dtype 兼容性——
int + str会静默变成object类型 - 更安全的替代:用
df1.add(df2, fill_value=0),它仍走对齐逻辑,但把缺失值当0处理,适合补零后计算
reindex() 和 align() 哪个更适合预处理对齐?
align() 更直接,reindex() 更灵活但容易漏配对。
-
df1.align(df2, join='outer')返回两个对齐后的 DataFrame,索引和列都统一为并集,天然配对,推荐用于后续运算前的一步式准备 -
df1.reindex(df2.index, columns=df2.columns)只对齐 df1,df2 不变,容易误以为“已经对齐”,实际 df2 还是原样,下一步运算仍可能出NaN - 性能影响:
align()内部做了两次reindex,比单次reindex稍慢,但逻辑清晰、不易出错 - 兼容性注意:Pandas 2.0+ 中
align()默认copy=True,大表慎用;可加copy=False避免内存翻倍
GroupBy 后的 agg 为什么也出现意外 NaN?
因为 agg 对每个分组单独调用函数,若某组为空(比如某类别在数据中根本没出现),结果就会是 NaN,这不是 bug,是设计行为。
- 常见错误现象:用
df.groupby('category').agg({'sales': 'sum'}),输出里某个 category 对应NaN,但查原始数据发现该 category 存在——其实是该 category 所有sales值全为NaN,sum()默认跳过NaN,空组返回NaN - 解决办法:显式控制空组行为,例如
.agg({'sales': ('sum', 'min_count=1')}(Pandas 2.1+)或先用dropna=False保全分组,再用fillna(0) - 关键点:GroupBy 的对齐发生在分组键层面,不是数值层面;
agg不做跨组填充,它只负责“把这一组的数喂给函数”
where()、甚至 concat() 的 join 参数。一旦索引不干净,问题会层层传导,最后在看似无关的操作里冒出来。Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










