根据条件将列值合并为 DataFrames 中的列表

Merge column values as a list in DataFrames based on a condition

我有一个类似

的DataFrame
| Item | Match | Score |
| ---- | ----- | ----- |
| A    | B     | 0.9   |
| A    | C     | 0.8   |
| A    | D     | 0.7   |
| A    | E     | 0.6   |
| B    | A     | 0.9   |
| B    | X     | 0.7   |
| C    | Y     | 0.45  |
| C    | Z     | 0.4   |

我想创建一个新的 DataFrame,其中包含列的所有匹配项 - 'Item' 作为 Match、Score 的列表。

| Item | MatchList | ScoreList       | Total Matches |
| ---- | --------- | --------------- | ------------- |
| A    | [B,C,D]   | [0.9,0.8,0.7]   | 4             |
| B    | [A,X]     | [0.9,0.7]       | 2             |
| C    | [Y,Z]     | [0.45,0.4]      | 2             |

我也想知道有多少这样的比赛,但只保留前三名。我已经按降序对每个项目的得分值进行了排序。现在,是否有可能获得像这样为匹配项、分数创建的列表以及总匹配项,这样如果有人想为某个项目查找超过 top3 的内容,他们可以根据该项目有多少匹配项来执行此操作。

我也发布了一个使用聚合的答案。接受更多建议。

我们可以做两个 groupby,第一个获取前 3 行,第二个获取 agg 格式

out = df.sort_values('Score',ascending=False).\
            groupby('Item').head(3).\
                groupby('Item').\
                   agg(MatchList = ('Match', list), 
                       ScoreList = ('Score', list), 
                       TotalMatches = ('Score', 'count')).reset_index()
Out[172]: 
  Item  MatchList        ScoreList  TotalMatches
0    A  [B, C, D]  [0.9, 0.8, 0.7]             3
1    B     [A, X]       [0.9, 0.7]             2
2    C     [Y, Z]      [0.45, 0.4]             2

我能够使用聚合函数获取列表:

df_result = df.groupby(['Item']).agg(lambda x: x.tolist())

我现在可以计算列表中的值以获得最后一列,然后过滤前 3 项以获得 'match' 和 'score'。

另一种在一行中计算的方法,使用一个 groupby(作为额外的选择!):

import pandas as pd
df = pd.DataFrame({'Item': ['A', 'A', 'A', 'A', 'B', 'B', 'C', 'C'],
                   'Match': ['B', 'C', 'D', 'E', 'A', 'X', 'Y', 'Z'],
                   'Score': [0.9, 0.8, 0.7, 0.6, 0.9, 0.7, 0.45, 0.4]})

df2 = df.sort_values("Score", ascending=False).\
    groupby('Item').agg(Item=pd.NamedAgg(column='Item', aggfunc=list),
                        Score=pd.NamedAgg(column='Score', aggfunc=list),
                        total_matches=pd.NamedAgg(column='Match', aggfunc='count')).\
        assign(Item=lambda x: [p[:3] for p in x['Item']],
               Score=lambda x: [p[:3] for p in x['Score']])

输出:

#Out: 
#           Item            Score  total_matches
#Item                                           
#A     [A, A, A]  [0.9, 0.8, 0.7]              4
#B        [B, B]       [0.9, 0.7]              2
#C        [C, C]      [0.45, 0.4]              2