Pandas中含NaN的索引匹配取值:如何保留原索引并避免报错?
问题描述
现有两个DataFrame df1 和 df2,数据如下:
# df1 index a 0 10 1 2 2 3 3 1 4 7 5 6 # df2 index a 0 1 1 2 2 4 3 3 4 20 5 5
通过滚动窗口(lookback=3)找出df1每个窗口内最大值对应的索引,代码如下:
lookback = 3 tdf = pd.DataFrame() tdf['a'] = df1.rolling(lookback).apply(lambda x: x.idxmax())
得到结果tdf:
id a 0 nan 1 nan 2 0 3 2 4 4 5 4
现在需要将tdf['a']中每个索引对应的df2的a列值存入tdf['b'],期望结果:
id b 0 nan 1 nan 2 1 3 4 4 20 5 20
尝试用tdf['b'] = df2.loc[tdf['a']]实现时,因tdf['a']包含NaN抛出异常;若先dropna()处理则会导致索引错乱,无法保留原位置的NaN。
解决方案
方法1:使用Series.map()
map()方法会自动忽略NaN值,遇到NaN时直接返回NaN,无需额外处理:
tdf['b'] = tdf['a'].map(df2['a'])
方法2:通过掩码精准赋值
先筛选出tdf['a']中非NaN的行,仅对这些行进行赋值操作,避免NaN传递给df2.loc:
# 生成非NaN的掩码 mask = tdf['a'].notna() # 对掩码覆盖的行赋值,用.values避免索引对齐问题 tdf.loc[mask, 'b'] = df2.loc[tdf.loc[mask, 'a'], 'a'].values
方法3:临时填充NaN后还原
先将NaN替换为一个不存在于df2索引中的值,赋值后再将对应位置还原为NaN:
# 临时用-1填充NaN(确保-1不是df2的索引) temp = tdf['a'].fillna(-1).astype(int) tdf['b'] = df2.loc[temp, 'a'] # 将临时填充的-1对应的结果还原为NaN tdf['b'] = tdf['b'].mask(temp == -1)
内容的提问来源于stack exchange,提问作者Masih Bahmani
相关产品推荐
相关产品推荐

