用熊猫数据框中的平均值正向填充NA

时间:2018-10-26 15:26:00

标签: python pandas dataframe nan

我有以下数据框,我想用前一个可用值除以NaN + 1的数目来填充正向NaN单元:

enter image description here

更新:我想迭代到最后的x列并执行该操作,columns.values是一个元组。(即它有多行)。

它应该与DataFrame.fillna(value=None, method=ffill)类似,但是没有最后一个可用值。

最终数据框应如下所示:

enter image description here

谢谢您的帮助。

2 个答案:

答案 0 :(得分:2)

您可以将GroupBytransform'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