每组第一次观察后 Groupby fillna 为 0

Groupby fillna with 0 after first observation per group

问题

有没有办法使用 groupby 用 0 填充缺失值,但只有在第一次出现观察后才可以?

例如开始

       id   spiq  nopiq   spiq  pstkq  dvy  dvpq  mibq  xidoq   miiq
2014    1   NaN   NaN     NaN   0.0   NaN   0.0   0.0 -0.122  0.000
2015    1   0.01  0.003   0.1   0.10  NaN   NaN   NaN -1.309  0.000
2016    1   0.04  0.003   NaN   0.10  NaN   0.10  0.10  NaN   NaN
2017    1   NaN   0.000   NaN   NaN   20    NaN   NaN  0.000  NaN
2018    1   0.05  0.000   NaN   0.0   NaN   0.0   0.0  0.000  0.000
2014    2   NaN   NaN     NaN   0.0   NaN   0.0   0.0 -0.122  0.000
2015    2   0.01  0.003   0.1   0.10  NaN   NaN   NaN -1.309  0.000
2016    2   0.04  0.003   NaN   0.10  NaN   0.10  0.10  NaN   NaN
2017    2   NaN   0.000   NaN   NaN   20    NaN   NaN  0.000  NaN
2018    2   0.05  0.000   NaN   0.0   NaN   0.0   0.0  0.000  0.000
2014    3   NaN   NaN     NaN   0.0   NaN   0.0   0.0 -0.122  0.000
2015    3   0.01  0.003   0.1   0.10  NaN   NaN   NaN -1.309  0.000
2016    3   0.04  0.003   NaN   0.10  NaN   0.10  0.10  NaN   NaN
2017    3   NaN   0.000   NaN   NaN   20    NaN   NaN  0.000  NaN
2018    3   0.05  0.000   NaN   0.0   NaN   0.0   0.0  0.000  0.000

需要

    id   spiq  nopiq   spiq  pstkq  dvy  dvpq  mibq  xidoq   miiq
2014    1   NaN   NaN     NaN   0.0   NaN   0.0   0.0  -0.122  0.000
2015    1   0.01  0.003   0.1   0.10  NaN   0.0   0.0  -1.309  0.000
2016    1   0.04  0.003   0.0   0.10  NaN   0.10  0.10  0.0    0.0
2017    1   0.0   0.000   0.0   0.0   20    0.0   0.0   0.0    0.0
2018    1   0.05  0.000   0.0   0.0   0.0   0.0   0.0   0.0    0.000
2014    2   NaN   NaN     NaN   0.0   NaN   0.0   0.0  -0.122  0.000
2015    2   0.01  0.003   0.1   0.10  NaN   0.0   0.0  -1.309  0.000
2016    2   0.04  0.003   0.0   0.10  NaN   0.10  0.10  0.0    0.0
2017    2   0.0   0.000   0.0   0.0   20    0.0   0.0   0.000  0.0
2018    2   0.05  0.000   0.0   0.0   0.0   0.0   0.0   0.000  0.000
2014    3   NaN   NaN     NaN   0.0   NaN   0.0   0.0  -0.122  0.000
2015    3   0.01  0.003   0.1   0.10  NaN   0.0   0.0  -1.309  0.000
2016    3   0.04  0.003   0.0   0.10  NaN   0.10  0.10  0.0    0.0
2017    3   0.0   0.000   0.0   0.0   20    0.0   0.0   0.000  0.0
2018    3   0.05  0.000   0.0   0.0   0.0   0.0   0.0   0.000  0.000

IIUC,这是一种方法,因为您不能向前填充零。

df.mask((df.groupby('id').ffill().notna() & 
         df.isna()).fillna(False), 0)

输出:

      id  spiq  nopiq  spiq.1  pstkq   dvy  dvpq  mibq  xidoq  miiq
2014   1   NaN    NaN     NaN    0.0   NaN   0.0   0.0 -0.122   0.0
2015   1  0.01  0.003     0.1    0.1   NaN   0.0   0.0 -1.309   0.0
2016   1  0.04  0.003     0.0    0.1   NaN   0.1   0.1  0.000   0.0
2017   1  0.00  0.000     0.0    0.0  20.0   0.0   0.0  0.000   0.0
2018   1  0.05  0.000     0.0    0.0   0.0   0.0   0.0  0.000   0.0
2014   2   NaN    NaN     NaN    0.0   NaN   0.0   0.0 -0.122   0.0
2015   2  0.01  0.003     0.1    0.1   NaN   0.0   0.0 -1.309   0.0
2016   2  0.04  0.003     0.0    0.1   NaN   0.1   0.1  0.000   0.0
2017   2  0.00  0.000     0.0    0.0  20.0   0.0   0.0  0.000   0.0
2018   2  0.05  0.000     0.0    0.0   0.0   0.0   0.0  0.000   0.0
2014   3   NaN    NaN     NaN    0.0   NaN   0.0   0.0 -0.122   0.0
2015   3  0.01  0.003     0.1    0.1   NaN   0.0   0.0 -1.309   0.0
2016   3  0.04  0.003     0.0    0.1   NaN   0.1   0.1  0.000   0.0
2017   3  0.00  0.000     0.0    0.0  20.0   0.0   0.0  0.000   0.0
2018   3  0.05  0.000     0.0    0.0   0.0   0.0   0.0  0.000   0.0

详情:

groupby 之后使用 ffill 用每个组的最后一个有效值填充 NaN,然后​​检查新创建的数据框以查看所有 non-NaN 值和 NaN 值的位置在原始 df 中使用 mask.

填充 0