Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何用数据帧中的前一个或下一个值替换NAN?_Python_Python 3.x_Pandas_Dataframe_Nan - Fatal编程技术网

Python 如何用数据帧中的前一个或下一个值替换NAN?

Python 如何用数据帧中的前一个或下一个值替换NAN?,python,python-3.x,pandas,dataframe,nan,Python,Python 3.x,Pandas,Dataframe,Nan,假设我有一个带有一些NaNs的数据帧: >>> 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

假设我有一个带有一些
NaN
s的数据帧:

>>> 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
我可以一列一列地循环整个数据帧,一个元素一个元素地循环,并直接设置值,但是有没有一种简单(最好是无循环)的方法来实现这一点?

您可以在数据帧上使用该方法,并将该方法指定为
ffill
(正向填充):

这种方法

将[s]上一个有效观测值向前传播到下一个有效观测值

相反,还有一个
bfill
方法

此方法不会就地修改数据帧-您需要将返回的数据帧重新绑定到变量,或者指定
inplace=True

df.fillna(method='ffill', inplace=True)
您可以与
method='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

还有一个直接的同义词函数,使事情更简单。

我在尝试此解决方案时注意到的一点是,如果在数组的开头或结尾有N/a,则ffill和bfill不太起作用。你两者都需要

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

ffill
现在有了自己的方法


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

在我的例子中,我们有来自不同设备的时间序列,但有些设备在某个时间段内无法发送任何值。所以我们应该为每个设备和时间段创建NA值,然后再填充NA

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

只有一列版本

  • 用上次有效值填写NAN
  • 用下一个有效值填写NAN

只是同意
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

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

南移

南替换


参考资料

正是我想要的,泰迪。我需要的正是这个来解决我的问题。填充前后。非常感谢,太好了。我需要这个解决方案。如果空白单元格位于列名索引中(即,两列没有名称,但确实有数据),那么有没有办法使用BPosior或FFILE来填充空白列索引单元格中的单元格,例如:DF= Pd?DataFrame({ COL1):(2, 4, 8),‘COL2’:(2, 0, 0)。,[(10, 2, 1)},index = [猎鹰','狗','蜘蛛' ')我如何使用bSufor或FFILE将第三列的名称更改为10(这是紧邻空白第三列名称下的行的值)?谢谢!
df[column_name].fillna(method='ffill', inplace=True)
df[column_name].fillna(method='backfill', inplace=True)
>>> 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
>>> 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
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
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