Python pandas fillna只有一行具有特定值

时间:2016-02-03 13:15:28

标签: python pandas nan fill

编辑:

我有(不是很简单)数据帧:

df = pd.DataFrame([1, 2, np.nan, np.nan, np.nan, np.nan, 3, 4
    , np.nan, np.nan, np.nan, 5], columns=['att1'])

     att1
0  1.0000
1  2.0000
2     nan
3     nan
4     nan
5     nan
6  3.0000
7  4.0000
8     nan
9     nan
10    nan
11 5.0000

我希望使用之前的NAN值填充NAN值,但最后NAN值除外。填写后,我希望最后NAN值为NAN。我怎么能这样做?

我想要这个结果:

     att1
0  1.0000
1  2.0000
2  2.0000
3  2.0000
4  2.0000
5     nan
6  3.0000
7  4.0000
8  4.0000
9  4.0000
10    nan
11 5.0000

我试过了:

df = df.fillna(value='missing', method='bfill', limit=1)
df = df.fillna(method='ffill')

但是第一行给出了这个错误:

ValueError: cannot specify both a fill method and value

为什么pandas 0.17.1 / Python 3.5有这个限制? 谢谢!

3 个答案:

答案 0 :(得分:2)

您可以在NaN中计算df['att1'],减去1,然后将其用作参数limitsfillna

import pandas as pd
import numpy as np

df = pd.DataFrame([1, 2, np.nan, np.nan, np.nan, np.nan, 3] , columns=['att1'])
print df
   att1
0     1
1     2
2   NaN
3   NaN
4   NaN
5   NaN
6     3

s = df['att1'].isnull().sum() - 1
df['att1'] = df['att1'].fillna('missing', limit=s)
print df
      att1
0        1
1        2
2  missing
3  missing
4  missing
5      NaN
6        3

编辑:

现在它更复杂了。

首先设置辅助列count,用于按isnullshiftastypecumsum计算列att1的连续值。然后countimport pandas as pd import numpy as np df = pd.DataFrame([1, 2, np.nan, np.nan, np.nan, np.nan, 3, 4 , np.nan, np.nan, np.nan, 5], columns=['att1']) print df df['count'] = (df['att1'].isnull() != df['att1'].isnull().shift()).astype(int).cumsum() print df att1 count 0 1 1 1 2 1 2 NaN 2 3 NaN 2 4 NaN 2 5 NaN 2 6 3 3 7 4 3 8 NaN 4 9 NaN 4 10 NaN 4 11 5 5 groupby

def f(x):
    att = x['att1'].isnull()
    if(att.all()):
        return x['att1'].fillna('missing', limit=att.sum() - 1)
    else:
        return x['att1']

print df.groupby(['count']).apply(f).reset_index(drop=True)

0           1
1           2
2     missing
3     missing
4     missing
5         NaN
6           3
7           4
8     missing
9     missing
10        NaN
11          5
Name: att1, dtype: object
count

解释专栏print (df['att1'].isnull() != df['att1'].isnull().shift()) 0 True 1 False 2 True 3 False 4 False 5 False 6 True 7 False 8 True 9 False 10 False 11 True Name: att1, dtype: bool

print (df['att1'].isnull() != df['att1'].isnull().shift()).astype(int)
0     1
1     0
2     1
3     0
4     0
5     0
6     1
7     0
8     1
9     0
10    0
11    1
Name: att1, dtype: int32
print (df['att1'].isnull() != df['att1'].isnull().shift()).astype(int).cumsum()
0     1
1     1
2     2
3     2
4     2
5     2
6     3
7     3
8     4
9     4
10    4
11    5
Name: att1, dtype: int32
resources :events

答案 1 :(得分:1)

一种可能稍微复杂一点的替代方法就是创建一个索引点列表,在该列表中您希望存在NaN(其中索引点不为空,但索引点之前为null)。然后,您只需转发填充数据并使用您创建的列表重新插入NaN。

import pandas as pd
import numpy as np
from numpy import nan as NA
df = pd.DataFrame([1, 2, np.nan, np.nan, np.nan, np.nan, 3, 4
    , np.nan, np.nan, np.nan, 5], columns=['att1'])

#create list of index points where you want NaNs to be be
Nan_ind = [x - 1 for x in xrange(1, df.index[-1] + 1) 
                if pd.notnull(df.loc[x, 'att1'])
                and pd.isnull(df.loc[x-1, 'att1'])]

#forward fillna             
df['att1'] = df['att1'].fillna(method = 'ffill')

#reinsert NaNs using your list of index points
df.loc[Nan_ind, 'att1'] = NA

答案 2 :(得分:0)

用“丢失”填充所有NaN。 您可以用NaN代替最后一个“缺失”。

df['att1'].fillna("missing",inplace=True)
df.iloc[[-2]].replace("missing",NaN)

使用负值向后查找iloc搜索索引。 -2返回'att1'列的前一个元素的值。