4 votes

Pandas : comment éliminer le 5ème percentile le plus bas pour chaque groupe indexé ?

J'ai le problème suivant avec python pandas (je suis relativement novice en la matière) : J'ai un jeu de données simple avec une colonne pour la date, et une colonne correspondante de valeurs. Je suis capable de trier ce Dataframe par date et par valeur en faisant ce qui suit :

df = df.sort_values(['date', 'value'],ascending=False)

J'obtiens ceci :

date       value
2019-11    100
2019-11    89
2019-11    87
2019-11    86   
2019_11    45
2019_11    33
2019_11    24
2019_11    11
2019_11    8
2019_11    5
2019-10    100 
2019-10    98
2019-10    96
2019-10    94
2019_10    94
2019_10    78
2019_10    74
2019_10    12
2019_10    3
2019_10    1

Maintenant, ce que je voudrais faire, c'est me débarrasser du cinquième percentile le plus bas pour la colonne des valeurs pour CHAQUE mois (chaque groupe). Je sais que je dois utiliser une méthode groupby, et peut-être aussi une fonction :

df = df.sort_values(['date', 'value'],ascending=False).groupby('date', group_keys=False).apply(<???>)

C'est au niveau du ? ?? que j'ai des difficultés. Je sais comment supprimer le 5ème percentile le plus bas sur un Dataframe trié dans son ensemble, par exemple en faisant :

df = df[df.value > df.value.quantile(.05)]

Cela a fait l'objet d'un autre post sur StackOverflow. Je sais que je peux aussi utiliser numpy pour faire cela, et que c'est beaucoup plus rapide, mais mon problème est vraiment de savoir comment appliquer cela à CHAQUE GROUPE indépendamment (chaque portion de la colonne de valeur triée par mois) dans le Dataframe, et pas seulement à l'ensemble du Dataframe.

Toute aide serait grandement appréciée Merci beaucoup, Bien à vous, Berti

7voto

jezrael Points 290608

Utilisez GroupBy.transform avec une fonction lambda pour les séries de même taille que l'original DataFrame donc filtre possible par boolean indexing :

df = df.sort_values(['date', 'value'],ascending=False)

q = df.groupby('date')['value'].transform(lambda x: x.quantile(.05))
df = df[df.value > q]
print (df)
       date  value
4   2019_11     45
5   2019_11     33
6   2019_11     24
7   2019_11     11
8   2019_11      8
14  2019_10     94
15  2019_10     78
16  2019_10     74
17  2019_10     12
18  2019_10      3
0   2019-11    100
1   2019-11     89
2   2019-11     87
10  2019-10    100
11  2019-10     98
12  2019-10     96

1voto

Chris A Points 12964

Vous pourriez créer votre propre fonction et apply il :

def remove_bottom_5_pct(arr):
    thresh = np.percentile(arr, 5)
    return arr[arr > thresh]

df.groupby('date', sort=False)['value'].apply(remove_bottom_5_pct)

[out]

date       
2019-11  0     100
         1      89
         2      87
         3      86
         4      45
         5      33
         6      24
         7      11
         8       8
2019-10  10    100
         11     98
         12     96
         13     94
         14     94
         15     78
         16     74
         17     12
         18      3
Name: value, dtype: int64

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