我有一个关于运动员比赛数据的巨大数据,如下所示:
Race_ID Athlete_ID Distance Rank
1 1 100 3
2 1 400 6
3 1 1500 1
4 1 100 6
5 1 100 1
6 1 1500 1
7 2 100 1
8 2 400 2
9 2 400 1
10 2 1500 6
11 2 1500 4
12 2 100 1
13 2 100 1
我想做一个名为Dist_Preference
的新专栏,通过计算运动员赢得那个距离的条件概率,看看运动员的距离是多少(100 (短),400 (中),1500 (长))。例如:
P(运动员1赢得100米赛跑这是100米赛跑)= 2/3
P(运动员1赢得400米赛跑这是400米赛跑)= 0/1 =0
P(运动员1赢得1500米赛跑这是1500米赛跑)= 2/2 =1
因此,运动员1显然有长跑的倾向。第四,所需列如下所示
Race_ID Athlete_ID Distance Rank Dist_Preference
1 1 100 3 1500
2 1 400 6 1500
3 1 1500 1 1500
4 1 100 6 1500
5 1 100 1 1500
6 1 1500 1 1500
7 2 100 1 100
8 2 400 2 100
9 2 400 1 100
10 2 1500 6 100
11 2 1500 4 100
12 2 100 1 100
13 2 100 1 100
我已经编写了一个子程序来完成这个任务,它定义了一个方法来计算上面提到的条件概率,然后使用.apply
,但是对于大型数据,它非常慢,我想知道是否有任何快速的方法来做到这一点。
非常感谢。
发布于 2022-10-01 12:06:11
创建一个布尔列:win
来识别获胜的比赛,然后用aggfunc mean
来计算概率,然后使用idxmax
根据获胜概率找到首选距离。
df['win'] = df['Rank'] == 1
prob = df.pivot_table('win', 'Athlete_ID', 'Distance')
df['preferred_dist'] = df['Athlete_ID'].map(prob.idxmax(1))
结果
Race_ID Athlete_ID Distance Rank win preferred_dist
0 1 1 100 3 False 1500
1 2 1 400 6 False 1500
2 3 1 1500 1 True 1500
3 4 1 100 6 False 1500
4 5 1 100 1 True 1500
5 6 1 1500 1 True 1500
6 7 2 100 1 True 100
7 8 2 400 2 False 100
8 9 2 400 1 True 100
9 10 2 1500 6 False 100
10 11 2 1500 4 False 100
11 12 2 100 1 True 100
12 13 2 100 1 True 100
发布于 2022-10-01 13:10:34
尝试:
df
Race_ID Athlete_ID Distance Rank
1 1 100 3
2 1 400 6
3 1 1500 1
4 1 100 6
5 1 100 1
6 1 1500 1
7 2 100 1
8 2 400 2
9 2 400 1
10 2 1500 6
11 2 1500 4
12 2 100 1
13 2 100 1
df1 = df.groupby(['Athlete_ID', 'Distance']).agg(nbr_of_races=('Rank', lambda x: len(x)),
nbr_of_races_won=('Rank', lambda x: len([i for i in x if i == 1]))).reset_index()
df1['performance'] = (df1['nbr_of_races_won']*100/df1['nbr_of_races']).round(2)
df1
Athlete_ID Distance nbr_of_races nbr_of_races_won performance
0 1 100 3 1 33.33
1 1 400 1 0 0.00
2 1 1500 2 2 100.00
3 2 100 3 3 100.00
4 2 400 2 1 50.00
5 2 1500 2 0 0.00
#sort by performance
df1 = df1.sort_values(['Athlete_ID', 'performance'], ascending=[True, False])
Athlete_ID Distance nbr_of_races nbr_of_races_won performance
2 1 1500 2 2 100.00
0 1 100 3 1 33.33
1 1 400 1 0 0.00
3 2 100 3 3 100.00
4 2 400 2 1 50.00
5 2 1500 2 0 0.00
#keep only the best performed Distance for each Athlete
df1 = df1.drop_duplicates('Athlete_ID')
Athlete_ID Distance nbr_of_races nbr_of_races_won performance
2 1 1500 2 2 100.0
3 2 100 3 3 100.0
#merge
df = df.merge(df1.loc[:, ['Athlete_ID', 'Distance']].rename(columns={"Distance": "preferred_dist"}), on='Athlete_ID', how='left')
df
Race_ID Athlete_ID Distance Rank preferred_dist
0 1 1 100 3 1500
1 2 1 400 6 1500
2 3 1 1500 1 1500
3 4 1 100 6 1500
4 5 1 100 1 1500
5 6 1 1500 1 1500
6 7 2 100 1 100
7 8 2 400 2 100
8 9 2 400 1 100
9 10 2 1500 6 100
10 11 2 1500 4 100
11 12 2 100 1 100
12 13 2 100 1 100
https://stackoverflow.com/questions/73918069
复制相似问题