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

2024-09-19 20:54:25 发布

您现在位置:Python中文网/ 问答频道 /正文

编辑:

我有(不是很简单)一个数据框:

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中有这个限制? 谢谢您!


Tags: columns数据编辑dataframedfvaluenpnan
3条回答

您可以在df['att1']中计数NaN,减法1,然后它用作limits^{}的参数:

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

编辑:

现在情况更复杂了。

因此,首先设置helper columncount,用于通过^{}^{}^{}^{}计算列att1的连续值。然后^{}按此列count^{}

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

另一种可能不太复杂的方法是创建一个索引点列表,在该列表中您希望有nan(其中索引点不为空,但前面的索引点为空)。然后,您只需向前填充数据并使用创建的列表重新插入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

菲娜所有的南与“失踪”。 最后一个“失踪”你可以换成南。

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

反向使用iloc搜索索引的负值。-2返回“att1”列的前一个元素的值。

相关问题 更多 >