【问题标题】:How to fill NA values for a set of Primary key grouping in Pandas Python如何在 Pandas Python 中为一组主键分组填充 NA 值
【发布时间】:2019-12-27 13:13:09
【问题描述】:

我的输入数据框如下所示:

df = pd.DataFrame({
    'key': [1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2],
    'col1': [20, np.nan, np.nan, np.nan, 25, np.nan, np.nan,np.nan, 20, np.nan,np.nan,np.nan,25, np.nan,np.nan, np.nan],
    'col2': [np.nan, 'a',np.nan, np.nan, np.nan, 'b', np.nan, np.nan,np.nan, 'c', np.nan, np.nan,np.nan, 'd', np.nan, np.nan],
    'col3': [np.nan, np.nan, 'aa', np.nan, np.nan,np.nan,'bb', np.nan,np.nan, np.nan,'cc', np.nan,np.nan, np.nan,'dd', np.nan],
    'col4': [np.nan, np.nan, np.nan, 50, np.nan, np.nan, np.nan, 200,np.nan, np.nan, np.nan, 100,np.nan, np.nan, np.nan, 300]
})

输入

我需要汇总“Key”和“col1”分组的所有列的缺失值。或者基本上用该分组中该列下唯一可用的非空值填充 NAN 值。

我尝试使用 bfill 和 ffill 方法进行 fillna,但它没有正确填充值,因为它从上组或下组中选择可用值(特别是组边界的单元格) 输出应如下所示:

【问题讨论】:

    标签: python pandas pandas-groupby


    【解决方案1】:

    第一个想法是使用GroupBy.apply 并使用Series.dropnaSeries 构造函数分别删除每一列:

    f = lambda x : x.apply(lambda y: pd.Series(y.dropna().to_numpy()))
    df1 = (df.groupby('key').apply(f)
             .drop('key', 1)
             .dropna(how='all')
             .reset_index(level=1, drop=True)
             .reset_index())
    print (df1)
       key  col1 col2 col3   col4
    0    1  20.0    a   aa   50.0
    1    1  25.0    b   bb  200.0
    2    2  20.0    c   cc  100.0
    3    2  25.0    d   dd  300.0
    

    或者通过DataFrame.stack使用reshape,通过GroupBy.cumcount添加计数器并通过Series.unstack进行reshape:

    df1 = df.set_index('key').stack().to_frame('val')
    df1 = (df1.set_index(df.groupby(level=[0,1]).cumcount(), append=True)['val']
             .unstack(1)
             .reset_index(level=1, drop=True)
             .reset_index())
    print (df1)
       key col1 col2 col3 col4
    0    1   20    a   aa   50
    1    1   25    b   bb  200
    2    2   20    c   cc  100
    3    2   25    d   dd  300
    

    或者您可以先创建列表,然后为DataFrame 展开:

    df1 = df.groupby('key').agg(lambda x: x.dropna().tolist())
    comp =[pd.DataFrame(df1[x].tolist(), index=df1.index) for x in df1.columns]
    df1 = (pd.concat(comp, axis=1, keys=df1.columns).stack()
            .reset_index(level=1, drop=True)
            .reset_index())
    print (df1)
       key  col1 col2 col3   col4
    0    1  20.0    a   aa   50.0
    1    1  25.0    b   bb  200.0
    2    2  20.0    c   cc  100.0
    3    2  25.0    d   dd  300.0
    

    【讨论】:

    • 谢谢。让我试试这个
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-21
    • 1970-01-01
    • 1970-01-01
    • 2017-12-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多