编辑:
我有(不是很简单)数据帧:
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有这个限制? 谢谢!
答案 0 :(得分:2)
您可以在NaN
中计算df['att1']
,减去1
,然后将其用作参数limits
至fillna
:
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
,用于按isnull
,shift
,astype
和cumsum
计算列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
和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'列的前一个元素的值。