尝试:
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