You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何向Pandas DataFrame直接添加Series作为新列会丢失行?

为什么直接给空DataFrame赋值Series列会丢失部分索引?

这是个非常好的问题,很多刚接触pandas的开发者都会对这个行为感到困惑,我来帮你拆解背后的逻辑:

先重现你的场景

首先看你用到的代码和结果:

import pandas as pd

s1 = pd.Series({1: 10, 2: 20, 3: 30, 4: 40}, name='s1')
s2 = pd.Series({3: 35, 4: 45, 5: 55, 6: 65}, name='s2')

# 直接赋值的方式
df = pd.DataFrame()
df['s1'] = s1
df['s2'] = s2

得到的结果只保留了s1的索引:

s1    s2
1  10   NaN
2  20   NaN
3  30  35.0
4  40  45.0

核心原因:赋值时的索引规则

直接给DataFrame添加列的行为遵循两个关键逻辑:

  1. 首次赋值固定DataFrame的索引:当你给一个空DataFrame添加第一列(df['s1'] = s1)时,pandas会自动把该Series的索引设置为DataFrame的索引,此时df的索引就固定为[1,2,3,4]了。
  2. 后续赋值仅做索引对齐,不扩展索引:当你添加第二列df['s2'] = s2时,pandas会以当前DataFrame已有的索引为基准,只匹配s2中索引重合的行(也就是3、4)填充值,而s2中索引5、6不在df的现有索引里,会直接被忽略,不会自动扩展df的索引范围。

为什么pd.concat能得到预期结果?

pd.concat([s1, s2], axis=1)的逻辑和直接赋值完全不同:
它会默认收集所有输入Series的索引,取索引的并集作为结果DataFrame的索引,然后对每个Series进行索引对齐,缺失的位置自动填充NaN。这就是为什么它能保留所有索引(1-6)的原因。

用赋值方式实现预期效果的替代方案

如果你想通过赋值的方式达到和concat一样的效果,可以先手动把DataFrame的索引设置为两个Series索引的并集,再进行赋值:

# 手动设置索引为两个Series索引的并集
df = pd.DataFrame(index=s1.index.union(s2.index))
df['s1'] = s1
df['s2'] = s2

这样得到的结果就和pd.concat一致了:

s1    s2
1  10.0   NaN
2  20.0   NaN
3  30.0  35.0
4  40.0  45.0
5   NaN  55.0
6   NaN  65.0

总结一下:直接赋值是以现有DataFrame的索引为基准做对齐,而pd.concat是以所有输入的索引并集为基准,这就是两者行为差异的核心。

内容的提问来源于stack exchange,提问作者Bilou

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 14:59:09