有条件地用熊猫填充()

时间:2021-03-20 06:33:48

标签: pandas

我想根据系列中的最后一个有效索引有条件地向前填充熊猫系列。例如,假设我们有这个系列:

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,因此这可行,但制作该系列的两个中间版本似乎不是一个很好的解决方案。

3 个答案:

答案 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)