我有以下数据框,我想用前一个可用值除以NaN + 1的数目来填充正向NaN单元:
更新:我想迭代到最后的x列并执行该操作,columns.values
是一个元组。(即它有多行)。
它应该与DataFrame.fillna(value=None, method=ffill)
类似,但是没有最后一个可用值。
最终数据框应如下所示:
谢谢您的帮助。
答案 0 :(得分:2)
您可以将GroupBy
和transform
与'first'
和'size'
一起使用。这与@sacul's solution 类似,但避免了lambda
限制矢量化优势的情况:
g = df.groupby(df['B'].notnull().cumsum())['B']
df['B'] = g.transform('first') / g.transform('size')
大型数据帧的性能差异为1,500倍:
# Python 3.6.0, Pandas 0.19.2
np.random.seed(0)
df = pd.DataFrame({'A':np.random.random(10),'B':[8,np.nan,np.nan,np.nan,np.nan,7,np.nan,np.nan,np.nan,np.nan]})
def jpp(df):
g = df.groupby(df['B'].notnull().cumsum())['B']
df['B'] = g.transform('first') / g.transform('size')
return df
def sac(df):
df['B'] = df.groupby(df.B.notnull().cumsum(),as_index=False)['B']\
.transform(lambda x: x.iloc[0]/x.size)
return df
df = pd.concat([df]*1000)
assert jpp(df).equals(sac(df))
%timeit jpp(df) # 5.07 ms per loop
%timeit sac(df) # 7.84 s per loop
答案 1 :(得分:1)
您可以使用groupby而不是ffill
:将notnull
产生的布尔值的累积和用作分组变量,然后通过取第一个值并将其除以变换B
根据每个组的大小:
df = pd.DataFrame({'A':np.random.random(10),'B':[8,np.nan,np.nan,np.nan,np.nan,7,np.nan,np.nan,np.nan,np.nan]})
>>> df
A B
0 0.899200 8.0
1 0.011443 NaN
2 0.227406 NaN
3 0.602941 NaN
4 0.214716 NaN
5 0.534166 7.0
6 0.519983 NaN
7 0.273051 NaN
8 0.454338 NaN
9 0.537210 NaN
df['B'] = (df.groupby(df.B.notnull().cumsum(),as_index=False)['B']
.transform(lambda x: x.iloc[0]/x.size))
>>> df
A B
0 0.899200 1.6
1 0.011443 1.6
2 0.227406 1.6
3 0.602941 1.6
4 0.214716 1.6
5 0.534166 1.4
6 0.519983 1.4
7 0.273051 1.4
8 0.454338 1.4
9 0.537210 1.4