首页 > 解决方案 > Pandas 数据框 - 创建由分组列中的字符串聚合组成的新列表列

问题描述

我一直在努力解决这个问题,感觉有点卡住了。

我有一个由这样的数据组成的数据框,命名为merged_frames(它是一个单帧,通过连接几个具有相同形状的帧创建):

          fqdn               source
0         site1.org          public_source_a
1         site2.org          public_source_a
2         site3.org          public_source_a
3         site1.org          public_source_b
4         site4.org          public_source_b
5         site1.org          public_source_b
6         site4.org          public_source_d                                 ...                 
7         site1.org          public_source_c
...

我要做的是在此框架中创建一个新列,其中包含按fqdn值分组时的源列表(理想情况下是 Python 列表,而不是命令分隔的字符串)。例如,基于此示例数据为fqdn值生成的数据site1.org应如下所示(这只是我所期望的子集,其他fqdn值也应该有行)

fqdn        source_list                                           source
site1.org   [public_source_a, public_source_b, public_source_c]   public_source_a
site1.org   [public_source_a, public_source_b, public_source_c]   public_source_b
site1.org   [public_source_a, public_source_b, public_source_c]   public_source_c
site1.org   [public_source_a, public_source_b, public_source_c]   public_source_d

一旦我获得了这种形式的数据,我将简单地删除该source列,然后用drop_duplicates(keep='first')它来删除除一个之外的所有数据。

我挖出了一些旧代码,大约 2 年前我曾经做过类似的事情,但它并没有像我预期的那样工作。自从我用 Pandas 做这样的事情已经有一段时间了。我所拥有的大致是:

    merged_frame['source_list'] = merged_frame.groupby(
        'fqdn', as_index=False)[['source']].aggregate(
            lambda x: list(x))['source']

这表现得很奇怪。虽然它实际上是source_list作为列表/数组创建的,但列中的数据不正确。此外,相当多的fqdn值具有 null/NaN 值source_list

我有一种感觉,我需要以完全不同的方式处理这个问题。对此的一点帮助将不胜感激,我现在​​完全被阻止并且没有取得任何进展,尽管我认为我在类似的数据集上使用了非常相关的示例代码块。

编辑:

从基础开始,我已经取得了一些进展,并且有以下几点,尽管这将字符串连接在一起而不是列出它们:

    merged_frame['source_list'] = merged_frame.groupby('fqdn').source.transform(','.join)

我很确定只需apply在这里我可以将它们拆分回list. 但是,一次性做到这一点的正确方法是什么,这样我就不需要再做不必要的事情joinapply(split(','))

标签: pythonpandas

解决方案


从上面的示例创建数据框:

df=pd.DataFrame({'fqdn':['site1.org','site2.org','site3.org','site1.org','site4.org','site1.org','site4.org','site1.org'],\
                 'source':['public_source_a','public_source_a','public_source_a','public_source_b','public_source_b','public_source_b',\
                 'public_source_d','public_source_c']})

使用 groupby 和 apply(list)

df_grouped=df.groupby('fqdn')['source'].unique().apply(list).reset_index()

与原始 df 合并并重命名列

result=pd.merge(df,df_grouped,on='fqdn',how='left')
result.rename(columns={'source_x':'source','source_y':'source_list'},inplace=True)

推荐阅读