【问题标题】:Pandas Get List of Unique Values in Column A for each Unique Value in Column BPandas 为 B 列中的每个唯一值获取 A 列中唯一值的列表
【发布时间】:2020-03-10 12:08:35
【问题描述】:

我发现这个问题很容易写出来,但很难用我的 Pandas Dataframe 应用。 在搜索任何“唯一值”和“列表”时,我只能得到获取列表中唯一值的答案。

有一个双 for 循环的蛮力解决方案,但必须有一个比 n^2 更快的 Pandas 解决方案。

我有一个包含两列的 DataFrame:名称和喜欢食物。

作为输出,我想要一个独特的 Likes Food 值列表对于每个唯一名称。

示例数据框 df

Index        Name       Likes Food

0            Tim        Pizza
1            Marie      Pizza
2            Tim        Pasta
3            Tim        Pizza
4            John       Pizza
5            Amy        Pizza
6            Amy        Sweet Potatoes
7            Marie      Sushi
8            Tim        Sushi

我知道如何根据 Likes Food 的唯一计数进行聚合和分组:

df.groupby( by='Name', as_index=False ).agg( {'Likes Food': pandas.Series.nunique} )
df.sort_values(by='Likes Food', ascending=False)
df.reset_index( drop=True )
>>>
Index        Name       Likes Food

0            Tim        3
1            Marie      2
2            Amy        2
3            John       1

但鉴于此,该 DataFrame 中每个 Name 的食物是什么?为了便于阅读,以列表的形式表示是很有意义的。列表排序无关紧要(并且可能很容易修复)。

示例输出

<code here>
>>>
Index        Name       Likes Food    Food List

0            Tim        3             [Pizza, Pasta, Sushi]
1            Marie      2             [Pizza, Sushi]
2            Amy        2             [Pizza, Sweet Potatoes]
3            John       1             [Pizza]

【问题讨论】:

    标签: python pandas list sorting dataframe


    【解决方案1】:

    要获得没有计数的输出,只需尝试unique

    df.groupby("Name")["Likes"].unique()
    Name
    Amy             [Pizza, Sweet Potatoes]
    John                            [Pizza]
    Marie                    [Pizza, Sushi]
    Tim               [Pizza, Pasta, Sushi]
    Name: Likes, dtype: object
    

    另外,你可以使用named aggregation

    df.groupby("Name").agg(**{"Likes Food": pd.NamedAgg(column='Likes', aggfunc="size"),
                              "Food List": pd.NamedAgg(column='Likes', aggfunc="nunique")}).reset_index()
        Name  Likes Food              Food List
    0    Amy           2         [Pizza, Sweet Potatoes]
    1   John           1                         [Pizza]
    2  Marie           2                  [Pizza, Sushi]
    3    Tim           3           [Pizza, Pasta, Sushi]
    

    【讨论】:

    • 还有如果pandas .25+,可以试试df.groupby('Name',sort=False).agg(Likes_Food=('Likes','nunique'),Food_List=('Likes','unique'))
    • @Quickbeam2k1 你应该使用nunique 而不是size,如果理解 OP 的问题
    • 这很好用。谢谢!我要花很长时间来学习这种语法......
    【解决方案2】:

    要让两列也排序,试试这个:

    df = df.groupby("Name")["Likes_Food"].aggregate({'counts': 'nunique',
                                                'food_list': 'unique'}).reset_index().sort_values(by='counts', ascending=False)
    df
       Name  counts               food_list
    3    Tim       3   [Pizza, Pasta, Sushi]
    0    Amy       2  [Pizza, SweetPotatoes]
    2  Marie       2          [Pizza, Sushi]
    1   John       1                 [Pizza]
    

    【讨论】:

      猜你喜欢
      • 2018-08-05
      • 1970-01-01
      • 1970-01-01
      • 2021-11-11
      • 2022-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-01
      相关资源
      最近更新 更多