有一个玩家在不同的团队(团队)中玩的数据框,所以我需要计算每个玩家的所有交叉点与他出现的团队玩家。
df = pd.DataFrame({ 'Team' : ['A', 'A', 'A', 'B', 'B', 'B', 'C', 'C', 'C', 'C', 'C'],
'Player' : ['Joe', 'Mike', 'Steve', 'Henry', 'Steve', 'Joe', 'Mike', 'Joe', 'Steve', 'Dan', 'Henry']
})
df
Out[6]:
Player Team
0 Joe A
1 Mike A
2 Steve A
3 Henry B
4 Steve B
5 Joe B
6 Mike C
7 Joe C
8 Steve C
9 Dan C
10 Henry C
输出必须是这样的。 P.S我手动完成,所以可能是错误。
Joe Mike 2
Joe Steve 3
Joe Henry 2
Joe Dan 1
Mike Joe 2
Mike Steve 2
Mike Dan 1
Mike Henry 1
Steve Joe 3
Steve Mike 2
Steve Henry 2
Steve Henry 1
Henry Steve 2
Henry Joe 2
Henry Mike 1
Henry Dan 1
Dan Steve 1
Dan Mike 1
Dan Joe 1
Dan Henry 1
解释:Joe出现在所有3支球队中,所以我只计算他出现在3支球队之间的其他球员的交叉点。与此同时,丹只在C队,我只考虑与C队其他球员的交叉。
我尝试通过groupby和笛卡尔产品加入来做,但无法弄清楚如何将它组合起来。愿有人帮忙解决这个问题吗?
gp = df.groupby('Player')['Team'].apply(lambda x: "%s" % ', '.join(x)).to_frame()
index = pd.MultiIndex.from_product([gp.index, gp.index], names = ["a", "b"])
new_df = pd.DataFrame(index = index).reset_index()
答案 0 :(得分:2)
鉴于你的输入DF:
df = pd.DataFrame({
'Team' : ['A', 'A', 'A', 'B', 'B', 'B', 'C', 'C', 'C', 'C', 'C'],
'Player' : ['Joe', 'Mike', 'Steve', 'Henry', 'Steve', 'Joe', 'Mike', 'Joe', 'Steve', 'Dan', 'Henry']
})
你可以在" Team"上将它合并到自己身上。列来获取您的交叉连接,过滤掉两列中相同的命名玩家,然后获取两对之间的团队数量,例如:
new_df = (
# Cartesian join dropping identical player pairs
df.merge(df, on='Team')[lambda row: row.Player_x != row.Player_y]
# Count unique number of overlaps and make column name a bit more usefu
.groupby(['Player_x', 'Player_y']).Team.size().rename('shared_teams')
# Optionally drop the index if not of use...
.reset_index()
)
这将给你:
Player_x Player_y shared_teams
0 Dan Henry 1
1 Dan Joe 1
2 Dan Mike 1
3 Dan Steve 1
4 Henry Dan 1
5 Henry Joe 2
6 Henry Mike 1
7 Henry Steve 2
8 Joe Dan 1
9 Joe Henry 2
10 Joe Mike 2
11 Joe Steve 3
12 Mike Dan 1
13 Mike Henry 1
14 Mike Joe 2
15 Mike Steve 2
16 Steve Dan 1
17 Steve Henry 2
18 Steve Joe 3
19 Steve Mike 2
注意 - 在分组之后删除重复的名称可能更有效,而不是之前。