根据条件将列值合并为 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
我有一个类似
的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