Reproduzierbarer Code für den Datensatz:

df = {'player' : ['a','a','a','a','a','a','a','a','a','b','b','b','b','b','b','b','b','b','c','c','c','c','c','c','c','c','c'],
      'week' : ['1','1','1','2','2','2','3','3','3','1','1','1','2','2','2','3','3','3','1','1','1','2','2','2','3','3','3'],
      'category': ['RES','VIT','MATCH','RES','VIT','MATCH','RES','VIT','MATCH','RES','VIT','MATCH','RES','VIT','MATCH','RES','VIT','MATCH','RES','VIT','MATCH','RES','VIT','MATCH','RES','VIT','MATCH'],
      'energy' : [75,54,87,65,24,82,65,42,35,25,45,87,98,54,82,75,54,87,65,24,82,65,42,35,25,45,98] }

df = pd.DataFrame(data= df)
df = df[['player', 'week', 'category','energy']]

Actual Dataset

Ich muss finden: "Finde für jeden Spieler die Woche, in der seine Energie maximal war, und zeige alle Kategorien und Energiewerte für diese Woche an."

Also habe ich getan:

1. Spieler und Woche als Index einstellen

2. Durchlaufen Sie den Index, um den Maximalwert der Energie zu ermitteln und den Wert zurückzugeben

df = df.set_index(['player', 'week'])

for index, row in df1.iterrows():
    group = df1.ix[df1['energy'].idxmax()]

Erhaltene Ausgabe:

                category energy
  player   week     
    b        2    RES      98
             2    VIT      54
             2   MATCH     82

Diese erhaltene Ausgabe bezieht sich auf die maximale Energie im gesamten Datensatz. Ich möchte das Maximum für jeden Spieler mit allen anderen Kategorien und dessen Energie für diese Woche.

Erwartete Ausgabe:

Expected Output

Ich habe versucht, die Groupby-Methode zu verwenden, wie in den Kommentaren vorgeschlagen.

df.groupby(['player','week'])['energy'].max().groupby(level=['player','week'])

Die erhaltene Ausgabe ist:

                energy  category
 player week        
   a     1        87    VIT
         2        82    VIT
         3        65    VIT
   b     1        87    VIT
         2        98    VIT
         3        87    VIT
   c     1        82    VIT
         2        65    VIT
         3        98    VIT
6
vishnu prashanth 18 Apr. 2018 im 21:09

3 Antworten

Beste Antwort

Finden Sie die maximale Energiewoche für jeden Spieler, wählen Sie dann diese Woche für den Spieler aus und verketten Sie das Ergebnis für alle Spieler.

max_energy_idx = df.groupby('player')['energy'].idxmax()  # 2, 12, 26
max_energy_weeks = df['week'].iloc[max_energy_idx]  # '1', '2', '3'
players = sorted(df['player'].unique())  # 'a', 'b', 'c'

result = pd.concat(
    [df.loc[(df['player'] == player) & (df['week'] == max_enery_week), :] 
     for player, max_enery_week in zip(players, max_energy_weeks)]
)
>>> result
   player week category  energy
0       a    1      RES      75
1       a    1      VIT      54
2       a    1    MATCH      87
12      b    2      RES      98
13      b    2      VIT      54
14      b    2    MATCH      82
24      c    3      RES      25
25      c    3      VIT      45
26      c    3    MATCH      98

Falls gewünscht, können Sie den Index für das Ergebnis festlegen:

result = result.set_index(['player', 'week'])
4
Alexander 18 Apr. 2018 im 18:50

Eine andere Lösung ohne Concat:

idx = df.groupby('player')['energy'].idxmax() 

coord = df.iloc[idx]

coord
player  week    category    energy
2   a   1   MATCH   87
12  b   2   RES 98
26  c   3   MATCH   98


df.set_index(['player', 'week']).loc[(df.iloc[idx].set_index(['player', 'week']).index)]
category    energy
player  week        
a   1   RES 75
    1   VIT 54
    1   MATCH   87
b   2   RES 98
    2   VIT 54
    2   MATCH   82
c   3   RES 25
    3   VIT 45
    3   MATCH   98
3
Boud 18 Apr. 2018 im 18:54

Wenn Sie Ihr df mit seinem ursprünglichen Index (dh vor dem Festlegen des Multiindex) verwenden, können Sie in einer Zeile zu Ihrem Ergebnis gelangen, indem Sie einen inneren Join mit .merge:

df.merge(df.loc[df.groupby('player').energy.idxmax(), ['player', 'week']])

#   player week category  energy
# 0      a    1      RES      75
# 1      a    1      VIT      54
# 2      a    1    MATCH      87
# 3      b    2      RES      98
# 4      b    2      VIT      54
# 5      b    2    MATCH      82
# 6      c    3      RES      25
# 7      c    3      VIT      45
# 8      c    3    MATCH      98
4
cmaher 18 Apr. 2018 im 19:12