【问题标题】:Pandas - groupby where each row has multiple values stored in listPandas - groupby,其中每一行都有多个值存储在列表中
【发布时间】:2019-07-07 17:09:42
【问题描述】:

我正在使用 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】:

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

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

    输出

    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
    

    【讨论】:

    • 像魅力一样工作!有趣的解决方案。以前从未见过 get_dummies 方法。感谢您关于构建流派的建议,这很有意义。
    • @bill 对于小型数据集来说还不错。但是Series.apply + Series.str 的组合使它成为两个非常慢的操作。对于更大的数据集,使用第二种方法并重新创建一个全新的DataFrame 可能要快得多
    猜你喜欢
    • 1970-01-01
    • 2021-10-09
    • 1970-01-01
    • 2019-01-02
    • 2019-11-06
    • 1970-01-01
    • 2018-08-20
    • 1970-01-01
    相关资源
    最近更新 更多