3 votes

Pandas max pour les lignes, top n max

J'essaie de créer des colonnes supérieures, qui sont le maximum de quelques lignes de colonnes. Pandas dispose d'une méthode nlargest mais je n'arrive pas à le faire fonctionner en rangs. Pandas dispose également de max y idxmax qui fait exactement ce que je veux faire, mais seulement pour la valeur maximale absolue.

df = pd.DataFrame(np.array([[1, 2, 3, 5, 1, 9], [4, 5, 6, 2, 5, 9], [7, 8, 9, 2, 5, 10]]), columns=['a', 'b', 'c', 'd', 'e', 'f'])
cols = df.columns[:-1].tolist()

df['max_1_val'] = df[cols].max(axis=1)
df['max_1_col'] = df[cols].idxmax(axis=1)

Salida:

    a   b   c   d   e   f   max_1_val   max_1_col
0   1   2   3   5   1   9   5           d
1   4   5   6   2   5   9   6           c
2   7   8   9   2   5   10  9           c

Mais j'essaie d'obtenir max_n_val et max_n_col, donc la sortie attendue pour les 3 premiers serait :

    a   b   c   d   e   f   max_1_val   max_1_col   max_2_val   max_2_col   max_3_val   max_3_col
0   1   2   3   5   1   9   5           d           3           c           2           b
1   4   5   6   2   5   9   6           c           5           b           5           e
2   7   8   9   2   5   10  9           c           8           b           7           a

1voto

jezrael Points 290608

Pour améliorer les performances, on utilise numpy.argsort pour les positions, pour l'ordre correct on utilise les 3 derniers éléments, inversés par l'indexation :

N = 3
a = df[cols].to_numpy().argsort()[:, :-N-1:-1]
print (a)
[[3 2 1]
 [2 4 1]
 [2 1 0]]

Puis obtenir les noms des colonnes en indexant sur c et pour réordonner les valeurs dans d utiliser este solution :

c = np.array(cols)[a]
d = df[cols].to_numpy()[np.arange(a.shape[0])[:, None], a]

Dernière création DataFrame s, rejoints par concat et réordonner les noms des colonnes par DataFrame.reindex :

df1 = pd.DataFrame(c).rename(columns=lambda x : f'max_{x+1}_col')
df2 = pd.DataFrame(d).rename(columns=lambda x : f'max_{x+1}_val')

c = df.columns.tolist() + [y for x in zip(df2.columns, df1.columns) for y in x]

df = pd.concat([df, df1, df2], axis=1).reindex(c, axis=1)
print (df)
   a  b  c  d  e   f  max_1_val max_1_col  max_2_val max_2_col  max_3_val  \
0  1  2  3  5  1   9          5         d          3         c          2   
1  4  5  6  2  5   9          6         c          5         e          5   
2  7  8  9  2  5  10          9         c          8         b          7   

  max_3_col  
0         b  
1         b  
2         a

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X