Pandas - groupby,其中每行有多个值存储在列表中

问题描述 投票:1回答:1

我正在使用last.fm监听数据,并且有一个如下所示的DataFrame:

           Artist Plays                                   Genres
0   John Coltrane    10             [jazz, modal jazz, hard bop]
1     Miles Davis    15  [jazz, cool jazz, modal jazz, hard bop]
2  Charlie Parker    20                            [jazz, bebop]

我希望按类型对数据进行分组,然后按每种类型的播放总和进行汇总,得到如下内容:

        Genre Plays
0        jazz    45
1  modal jazz    25
2    hard bop    25
3       bebop    20
4   cool jazz    15

一直试图弄清楚这一段时间,但似乎无法找到解决方案。我是否需要更改流派数据的存储方式?

我找到了解决类似问题的this post,但该用户只想查看每个列表值的计数。这让我大约一半,但我无法弄清楚如何使用它来聚合数据框中的另一列。

python pandas
1个回答
1
投票

一般情况下,您不应该将列表存储在DataFrame中,所以是的,可能最好更改它们的存储方式。有了它,你可以使用一些join + str.get_dummies + .multiply。选择一个没有出现在任何字符串中的sep

sep = '*'
df.Genres.apply(sep.join).str.get_dummies(sep=sep).multiply(df.Plays, axis=0).sum()

Output

bebop         20
cool jazz     15
hard bop      25
jazz          45
modal jazz    25
dtype: int64

如果您的列表按行拆分,则可以使用更简单的表单:

import pandas as pd
df1 = pd.concat([pd.DataFrame(df.Genres.values.tolist()).stack().reset_index(1, drop=True).to_frame('Genres'),
                 df[['Plays', 'Artist']]], axis=1)

       Genres  Plays          Artist
0        jazz     10   John Coltrane
0  modal jazz     10   John Coltrane
0    hard bop     10   John Coltrane
1        jazz     15     Miles Davis
1   cool jazz     15     Miles Davis
1  modal jazz     15     Miles Davis
1    hard bop     15     Miles Davis
2        jazz     20  Charlie Parker
2       bebop     20  Charlie Parker

在流派中将其简化为:

df1.groupby('Genres').Plays.sum()

Genres
bebop         20
cool jazz     15
hard bop      25
jazz          45
modal jazz    25
Name: Plays, dtype: int64
© www.soinside.com 2019 - 2024. All rights reserved.