Pandas中DataFrame列(Series)索引与主表不一致为何运算结果不符合预期?
问题解答
根本原因
这不是Pandas的Bug,是Pandas两个核心设计特性共同作用的正常结果:
- Pandas中直接对DataFrame列做赋值(
b = df.a)得到的是原列的视图引用,而非独立拷贝,对视图的索引修改会同步作用到原DataFrame的对应列 - Pandas的Series之间做算术运算时,会默认按索引自动对齐,而非按位置顺序计算
具体执行过程拆解
- 执行
b = df.a时,b和df.a指向同一份Series数据,此时两者的索引都是[0,1,2],对应值为[1,2,3] - 执行
b.index = b.index + 1时,因为是视图引用,df.a的索引也被同步修改为[1,2,3],对应值仍为[1,2,3] - 执行
df['b'] = b时,Pandas会按df的行索引[0,1,2]和b的索引[1,2,3]对齐赋值:- 索引0在b中不存在,因此
df.loc[0, 'b'] = NaN - 索引1对应b中值1,索引2对应b中值2,最终
df['b']列的索引为[0,1,2],值为[NaN, 1, 2]
- 索引0在b中不存在,因此
- 执行
df.a - df.b时,两个Series的索引分别是[1,2,3](df.a)和[0,1,2](df.b),会先取索引并集[0,1,2,3]再对齐计算:- 索引0:df.a无对应值,结果为NaN
- 索引1:df.a值为1,df.b值为1,计算得0
- 索引2:df.a值为2,df.b值为2,计算得0
- 索引3:df.b无对应值,结果为NaN
完全匹配实际输出结果。
实现预期结果的方案
如果要得到预期的输出,可以在取列时显式做拷贝,避免修改索引影响原列:
import pandas as pd df = pd.DataFrame({'a': [1,2,3]}) b = df.a.copy() # 显式拷贝,得到独立的Series b.index = b.index + 1 df['b'] = b print(df.a - df.b)
如果确定要按位置对齐运算,也可以直接取numpy数组计算:
print(df.a.values - df.b.values)
内容的提问来源于stack exchange,提问作者Parapapuppolo
相关产品推荐
相关产品推荐

