如何在 Pandas Python 中为一组主键分组填充 NA 值

Posted

技术标签:

【中文标题】如何在 Pandas Python 中为一组主键分组填充 NA 值【英文标题】:How to fill NA values for a set of Primary key grouping in Pandas Python 【发布时间】: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,但它没有正确填充值,因为它从上组或下组中选择可用值(特别是组边界的单元格) 输出应如下所示:

【问题讨论】:

【参考方案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

【讨论】:

谢谢。让我试试这个

以上是关于如何在 Pandas Python 中为一组主键分组填充 NA 值的主要内容,如果未能解决你的问题,请参考以下文章

如何在 ASP.Net 中为一组 Web 请求发送身份验证标头

在 aws devicefarm 中为一组特定的 android 手机创建设备池

pandas:将具有相同值的连续行分组为一组

如何在 python 中为 pandas 创建一个“非”过滤器

数据完整性

Pandas - Python 2.7:如何将时间序列索引转换为一天中的秒数?