【问题标题】:Forward filling NA with average value in Pandas Dataframes用 Pandas Dataframes 中的平均值向前填充 NA
【发布时间】:2019-03-31 09:37:47
【问题描述】:

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

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

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

最终的数据框应该是这样的:

提前感谢您的帮助。

【问题讨论】:

    标签: python pandas dataframe pandas-groupby nan


    【解决方案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
    

    【讨论】:

    • 我看起来这行得通。我已经更新了一些关于修复哪些列的规范。
    【解决方案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
    

    【讨论】:

      猜你喜欢
      • 2020-06-08
      • 1970-01-01
      • 1970-01-01
      • 2012-02-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-25
      相关资源
      最近更新 更多