假设我有一个带有一些nan的数据框架:

>>> import pandas as pd
>>> df = pd.DataFrame([[1, 2, 3], [4, None, None], [None, None, 9]])
>>> df
    0   1   2
0   1   2   3
1   4 NaN NaN
2 NaN NaN   9

我需要做的是将每个NaN替换为上面同一列中的第一个非NaN值。假定第一行永远不会包含NaN。对于前面的例子,结果是

   0  1  2
0  1  2  3
1  4  2  3
2  4  2  9

我可以一列一列地循环整个DataFrame,一个元素一个元素地循环,然后直接设置值,但是有没有一种简单的(最好是无循环的)方法来实现这一点呢?


当前回答

你可以在DataFrame上使用fillna方法,并指定该方法为ffill(前向填充):

>>> df = pd.DataFrame([[1, 2, 3], [4, None, None], [None, None, 9]])
>>> df.fillna(method='ffill')
   0  1  2
0  1  2  3
1  4  2  3
2  4  2  9

这个方法…

将[s]最后一个有效观测值转发到下一个有效观测值

相反,还有一个bfill方法。

这个方法不会修改DataFrame inplace -你需要将返回的DataFrame重新绑定到一个变量,或者指定inplace=True:

df.fillna(method='ffill', inplace=True)

其他回答

你可以在DataFrame上使用fillna方法,并指定该方法为ffill(前向填充):

>>> df = pd.DataFrame([[1, 2, 3], [4, None, None], [None, None, 9]])
>>> df.fillna(method='ffill')
   0  1  2
0  1  2  3
1  4  2  3
2  4  2  9

这个方法…

将[s]最后一个有效观测值转发到下一个有效观测值

相反,还有一个bfill方法。

这个方法不会修改DataFrame inplace -你需要将返回的DataFrame重新绑定到一个变量,或者指定inplace=True:

df.fillna(method='ffill', inplace=True)

只有一个列版本

用最后一个有效值填充NAN

df[column_name].fillna(method='ffill', inplace=True)

用下一个有效值填充NAN

df[column_name].fillna(method='backfill', inplace=True)

ffill现在有自己的方法pd. dataframe。ffill

df.ffill()

     0    1    2
0  1.0  2.0  3.0
1  4.0  2.0  3.0
2  4.0  2.0  9.0

只是同意ffill方法,但一个额外的信息是,你可以限制向前填充关键字参数限制。

>>> import pandas as pd    
>>> df = pd.DataFrame([[1, 2, 3], [None, None, 6], [None, None, 9]])

>>> df
     0    1   2
0  1.0  2.0   3
1  NaN  NaN   6
2  NaN  NaN   9

>>> df[1].fillna(method='ffill', inplace=True)
>>> df
     0    1    2
0  1.0  2.0    3
1  NaN  2.0    6
2  NaN  2.0    9

现在使用limit关键字参数

>>> df[0].fillna(method='ffill', limit=1, inplace=True)

>>> df
     0    1  2
0  1.0  2.0  3
1  1.0  2.0  6
2  NaN  2.0  9

公认的答案是完美的。我有一个相关但略有不同的情况,我必须在前面填写,但只能在小组中。如果有人有同样的需求,要知道fillna适用于DataFrameGroupBy对象。

>>> example = pd.DataFrame({'number':[0,1,2,nan,4,nan,6,7,8,9],'name':list('aaabbbcccc')})
>>> example
  name  number
0    a     0.0
1    a     1.0
2    a     2.0
3    b     NaN
4    b     4.0
5    b     NaN
6    c     6.0
7    c     7.0
8    c     8.0
9    c     9.0
>>> example.groupby('name')['number'].fillna(method='ffill') # fill in row 5 but not row 3
0    0.0
1    1.0
2    2.0
3    NaN
4    4.0
5    4.0
6    6.0
7    7.0
8    8.0
9    9.0
Name: number, dtype: float64