web-dev-qa-db-fra.com

Ajouter une colonne à la fin de Pandas DataFrame contenant la moyenne des données précédentes

J'ai un DataFrame ave_data qui contient les éléments suivants:

ave_data

Time        F7           F8            F9  
00:00:00    43.005593    -56.509746    25.271271  
01:00:00    55.114918    -59.173852    31.849262  
02:00:00    63.990762    -64.699492    52.426017

Je veux ajouter une autre colonne à cette trame de données, contenant la moyenne des valeurs sous les colonnes F7, F8 et F9 pour chaque ligne.

Le ave_data DataFrame peut changer de taille lorsque mon code lit plus tard dans différents fichiers Excel, donc la méthode doit être générique (c'est-à-dire ajouter la colonne contenant la moyenne toujours comme dernière colonne du DataFrame, pas dans la colonne numéro 4)

desired output

Time        F7           F8            F9           Average
00:00:00    43.005593    -56.509746    25.271271    4.25  
01:00:00    55.114918    -59.173852    31.849262    9.26
02:00:00    63.990762    -64.699492    52.426017    17.24
12
LinnK

Vous pouvez prendre une copie de votre df en utilisant copy() puis appeler mean et transmettre les paramètres axis=1 et numeric_only=True pour que la moyenne soit calculée par ligne et pour ignorer les colonnes non numériques, lorsque vous procédez comme suit, la colonne est toujours ajoutée à la fin:

In [68]:

summary_ave_data = df.copy()
summary_ave_data['average'] = summary_ave_data.mean(numeric_only=True, axis=1)
summary_ave_data
Out[68]:
                 Time         F7         F8         F9    average
0 2015-07-29 00:00:00  43.005593 -56.509746  25.271271   3.922373
1 2015-07-29 01:00:00  55.114918 -59.173852  31.849262   9.263443
2 2015-07-29 02:00:00  63.990762 -64.699492  52.426017  17.239096
11
EdChum

@LaangeHaare ou toute autre personne curieuse, je viens de la tester et la partie copie de la réponse acceptée semble inutile (peut-être que je manque quelque chose ...)

vous pouvez donc simplifier cela avec:

df['average'] = df.mean(numeric_only=True, axis=1)

J'aurais simplement ajouté ceci en tant que commentaire mais je n'ai pas la réputation

4
kt-0

Dans le cas commun, si vous souhaitez utiliser des colonnes spécifiques, vous pouvez utiliser:

df['average'] = df[['F7','F8']].mean(axis=1)

où axe = 1 représente l'action en ligne (en utilisant les valeurs de colonne pour chaque ligne pour calculer la moyenne dans la colonne "moyenne")

Ensuite, vous voudrez peut-être trier par cette colonne:

df.sort_values(by='average',ascending=False, inplace=True)

où inplace = True signifie appliquer une action à la trame de données au lieu de calculer sur la copie.

1
Sergey Zaitsev

df.assign est spécialement conçu à cet effet. Il renvoie une copie pour éviter de modifier la trame de données d'origine et/ou d'augmenter SettingWithCopyWarning. Cela fonctionne comme suit:

data_with_ave = ave_data.assign(average = ave_data.mean(axis=1, numeric_only=True))

Cette fonction peut également créer plusieurs colonnes en même temps:

data_with_ave = ave_data.assign(
                    average = ave_data.mean(axis=1, numeric_only=True),
                    median = ave_data.median(axis=1, numeric_only=True)
)

À partir de pandas 0,36, vous pouvez même référencer une colonne que vous venez de créer pour en créer une autre:

data_with_ave = ave_data.assign(
                    average = ave_data.mean(axis=1, numeric_only=True),
                    isLarge = lambda df: df['average'] > 10
)
0
johnDanger