将 pandas GroupBy 中的多个列值聚合为 dict

Posted

技术标签:

【中文标题】将 pandas GroupBy 中的多个列值聚合为 dict【英文标题】:Aggregate multiple column values in pandas GroupBy as a dict 【发布时间】:2020-11-04 15:31:23 【问题描述】:

我有一个与此问题相关的问题:Aggregate column values in pandas GroupBy as a dict

我的输入数据有以下列:

例如,输入将具有以下格式

language, product_id, shelf_id, rank, fiction, pages
English, 742005, 4560, 10.2, 1.0, 456 
English, 6000075389352, 4560, 49, 1.0, 234
French, 899883993, 4560, 32, 0.0, 125
French, 731317391, 7868, 81, 1.0, 576
French, 235678655, 7868, 12, 1.0, 235

我想对语言和货架 ID 列执行“分组”,并获取每个产品 ID 的剩余属性列表。预期的输出应具有以下格式:

Language, shelf_id, product_id: [rank, fiction, pages] 用于每个分组记录。

对于给定的输入,我的 DESIRED OUTPUT 将如下:

language, shelf_id, mapping
English, 4560, 742005: [10.2, 1.0, 456], 6000075389352: [49, 1.0, 234]
French, 4560, 899883993: [32, 0.0, 125]
French, 7868, 731317391: [81, 1.0, 576], 235678655: [12, 1.0, 235]

如果只需要考虑一列(在结果字典中),上述帖子中提供的解决方案可以很好地解决问题:

df = pd.read_csv('file.csv', header=None)  
df.columns = ['Lang', 'product_id', 'shelf_id', 'rank_id']
(df.groupby(['Lang', 'shelf_id'], as_index=False)
   .apply(lambda x: dict(zip(x['product_id'], x['rank_id'])))
   .reset_index(name='mapping'))

这会产生:

      Lang  shelf_id                              mapping
0  English      4560  742005: 10.2, 6000075389352: 49.0
1   French      4560                    899883993: 32.0
2   French      7868   731317391: 81.0, 235678655: 12.0

谁能帮助我根据我的情况调整这个解决方案?任何建议将不胜感激。

【问题讨论】:

【参考方案1】:

想法是创建一个新系列s,其中包含tuples 中的项目,其中元组中的第一项是product_id,第二项是包含来自列rankfiction 和@ 的相应值的列表987654327@,接下来我们使用Series.groupbylanguageshelf_id 上的系列s 进行分组,并将数据聚合为字典:

s = pd.Series([(k, v) for k, *v in zip(df['product_id'],
                                       df['rank'], df['fiction'], df['pages'])])
                                       
df = s.groupby([df['language'], df['shelf_id']]).agg(
               lambda d: dict(d.tolist())).reset_index(name='mapping')

详情:

#print(s)
0           (742005, [10.2, 1.0, 456]) # --> product_id: [rank, fiction, pages]
1    (6000075389352, [49.0, 1.0, 234])
2        (899883993, [32.0, 0.0, 125])
3        (731317391, [81.0, 1.0, 576])
4        (235678655, [12.0, 1.0, 235])
dtype: object

# print(df)
  language  shelf_id                                                      mapping
0  English      4560  742005: [10.2, 1.0, 456], 6000075389352: [49.0, 1.0, 234]
1   French      4560                                899883993: [32.0, 0.0, 125]
2   French      7868   731317391: [81.0, 1.0, 576], 235678655: [12.0, 1.0, 235]

【讨论】:

谢谢!这正是我所需要的。我也很喜欢你的解释。您的解决方案非常完美——简单、清晰且非常符合 Python 风格。

以上是关于将 pandas GroupBy 中的多个列值聚合为 dict的主要内容,如果未能解决你的问题,请参考以下文章

具有多个聚合的 pyspark groupBy(如 pandas)

数据分析—Pandas 中的分组聚合Groupby 高阶操作

Pandas groupby 在保留多个聚合的组内排序

pandas使用groupby函数进行分组聚合并使用agg函数将每个分组特定变量对应的多个内容组合到一起输出(merging content within a specific column of g

Groupby并在pandas中执行多个函数的聚合

使用 pandas GroupBy 和时间序列重采样的平均聚合