假设我有一个带有NaN的DataFrame:

>>> 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的逐列,逐元素并直接设置值,但是有一种简单(最佳无循环)的方式来实现这一目标吗?

#1 楼

您可以在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


此方法...


将上一个有效观测值传播到下一个有效观测值


相反,还有一个bfill方法。

该方法没有无需就地修改DataFrame-您需要将返回的DataFrame重新绑定到变量,或者指定inplace=True

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


评论


如果空白单元格在列名称索引中(即,几个列没有名称但确实有数据),该怎么办?有没有一种方法可以使用bfill或ffill来填充空白列索引单元格中的单元格。例如:df = pd.DataFrame({'col1':[2,4,8],'col2':[2,0,0],'':[10,2,1]} ,index = ['falcon','dog','spider']])我如何使用bfill或ffill将第三列的名称更改为10(这是空白的第三列名称正下方的行的值? 谢谢!

– GbG
8月3日,17:58



#2 楼

公认的答案是完美的。我遇到了一个相关但略有不同的情况,我必须向前填写,但只能在小组内填写。如果有人有相同的需求,请知道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


评论


正是我要找的

–托尼
17/09/22在11:18

#3 楼

您可以将pandas.DataFrame.fillnamethod='ffill'选项一起使用。 'ffill'代表“向前填充”,并将向前传播最后一个有效观察值。替代方法是'bfill',它的工作方式相同,但是向后。

import pandas as pd

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

print(df)
#   0  1  2
#0  1  2  3
#1  4  2  3
#2  4  2  9


还有一个直接的同义词功能pandas.DataFrame.ffill,使事情变得更简单。

#4 楼

我在尝试此解决方案时注意到的一件事是,如果您在数组的开头或结尾处都没有N / A,则填充和填充将无法正常工作。两者都需要。

In [224]: df = pd.DataFrame([None, 1, 2, 3, None, 4, 5, 6, None])

In [225]: df.ffill()
Out[225]:
     0
0  NaN
1  1.0
...
7  6.0
8  6.0

In [226]: df.bfill()
Out[226]:
     0
0  1.0
1  1.0
...
7  6.0
8  NaN

In [227]: df.bfill().ffill()
Out[227]:
     0
0  1.0
1  1.0
...
7  6.0
8  6.0


评论


辉煌。我正是需要这个来解决我的问题。填充之前和之后。非常感谢。

–普罗米修斯
18年4月22日在16:46

大。我需要这个解决方案。谢谢

– unkrat
19 Mar 9 '19 at 15:44

#5 楼

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


#6 楼

仅一列版本


用最后一个有效值填充NAN


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




>
用下一个有效值填充NAN


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


#7 楼

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

>>> 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


#8 楼

就我而言,我们具有来自不同设备的时间序列,但是某些设备在一段时间内无法发送任何值。因此,我们应该为每个设备和每个时间段创建NA值,然后再执行fillna。

df = pd.DataFrame([["device1", 1, 'first val of device1'], ["device2", 2, 'first val of device2'], ["device3", 3, 'first val of device3']])
df.pivot(index=1, columns=0, values=2).fillna(method='ffill').unstack().reset_index(name='value')


结果:

        0   1   value
0   device1     1   first val of device1
1   device1     2   first val of device1
2   device1     3   first val of device1
3   device2     1   None
4   device2     2   first val of device2
5   device2     3   first val of device2
6   device3     1   None
7   device3     2   None
8   device3     3   first val of device3


#9 楼

您可以使用fillna删除或替换NaN值。

NaN删除

import pandas as pd

df = pd.DataFrame([[1, 2, 3], [4, None, None], [None, None, 9]])

df.fillna(method='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


NaN替换

df.fillna(0) # 0 means What Value you want to replace 
     0    1    2
0  1.0  2.0  3.0
1  4.0  0.0  0.0
2  0.0  0.0  9.0


参考pandas.DataFrame.fillna