我想根据系列中的最后一个有效索引有条件地向前填充熊猫系列。例如,假设我们有这个系列:
import pandas as pd
ser = pd.Series(['a', 'b', 'b', pd.NA, 'c', pd.NA, pd.NA, 'd', pd.NA])
ser
0 a
1 b
2 b
3 <NA>
4 c
5 <NA>
6 <NA>
7 d
8 <NA>
仅当最后一个有效索引不是 2 时,我才想 ffill() 系列。这是所需的结果:
0 a
1 b
2 b
3 <NA>
4 c
5 c
6 c
7 d
8 d
我想出了这种有效的方法,但似乎不是一个很好的答案。有没有更优雅的方法来做到这一点?
ffilled = ser.ffill()
shifted = ser.shift(1)
result = ffilled.loc[(~pd.isna(ser)) | (shifted != 'b')]
result
0 a
1 b
2 b
4 c # -> index 3 does not get forward filled
5 c
6 c
7 d
8 d
将此结果与原始结果连接回会在索引 3 处插入 NaN,因此这可行,但制作该系列的两个中间版本似乎不是一个很好的解决方案。
答案 0 :(得分:2)
你也可以简单地使用布尔掩码来做到这一点:-
result=ser[~(ser.index==3)].ffill()
最后使用reindex()
方法:-
result=result.reindex(ser.index)
现在,如果您打印 result
,您将获得预期的输出:-
0 a
1 b
2 b
3 NaN
4 c
5 c
6 c
7 d
8 d
如果你想用 <NA>
代替 nan
值,那么:-
result.fillna('<NA>',inplace=True)
现在,如果您打印 result
,您将获得与您想要的完全相同的系列:-
0 a
1 b
2 b
3 <NA>
4 c
5 c
6 c
7 d
8 d
答案 1 :(得分:0)
nan 处理这种事情可能有点笨拙。我会试试这个:
# generate fill values
fvals = ser.ffill().where(ser.index != 3)
ser.fillna(fvals)
输出:
0 a
1 b
2 b
3 NaN
4 c
5 c
6 c
7 d
8 d
dtype: object
答案 2 :(得分:0)
此问题的其他答案硬编码删除特定索引,该索引不适用于看不见的系列。我意识到问题中使用的系列的转换版本实际上并不是必需的,所以我选择了这个:
result = ffilled.loc[(~pd.isna(ser)) | (ffilled != 'b')]
result
0 a
1 b
2 b
4 c
5 c
6 c
7 d
8 d
这也解决了问题方法存在的一个错误,即“b”值之后的多个 NA 值不会被省略。
@AnuragDabas 使用 reindex 是将 NaN 放回索引 3 的好方法,然后可以根据需要使用 fillna() 填充。
result = result.reindex(ser.index)