4
votes

Comment parcourir les en-têtes de colonne dans les pandas

J'essaie de parcourir les en-têtes de colonne et de remplir une liste contenant les revenus moyens pour chaque catégorie. J'obtiens cette erreur et j'ai essayé un tas de choses différentes pour essayer de la corriger. Donc ma dataframe ressemble à ceci (on dirait que je n'ai pas assez de points pour coller une image, mais voici un lien vers elle): chaque ligne dans la dataframe représente un film idividual. colonne revenue_adj remplie avec des valeurs de revenus, une colonne pour chaque genre remplie avec TRUE / FALSE indiquant que le film appartient à ce genre spécifique.

ce code fonctionne bien, mais je voudrais le faire dans une boucle for à la place

df[gen] == True
'@df[gen] == True'
'@gen == True'

J'ai essayé la boucle suivante sans succès:

genheads = ['action', 'adventure', 'animation', 'comedy', 'crime', 'documentary', 'drama', 'family']

genres2 = genheads
genrev = []
for gen in genres2:
    genrev.append(df.query('gen == True')['revenue_adj'].mean())

J'obtiens une erreur disant "gen n'est pas défini" Au lieu de gen, j'ai essayé:

genrev1= df.query('action == True')['revenue_adj'].mean()
genrev2 = df.query('adventure == True')['revenue_adj'].mean()
genrev3 = df.query('animation == True')['revenue_adj'].mean()
genrev4 = df.query('comedy == True')['revenue_adj'].mean()
genrev5 = df.query('crime == True')['revenue_adj'].mean()
genrev6 = df.query('documentary == True')['revenue_adj'].mean()
genrev7 = df.query('drama == True')['revenue_adj'].mean()
genrev8 = df.query('family == True')['revenue_adj'].mean()

J'ai été coincé là-dessus pendant plusieurs semaines et toute aide à ce sujet serait tellement appréciée !!


0 commentaires

5 Réponses :


1
votes

Vous essayez d'utiliser la variable gen dans la chaîne, mais vous ne pouvez pas le faire de cette façon.

Un correctif serait de changer la ligne en:

genrev.append(df.query(f'{gen} == True')['revenue_adj'].mean())

étant donné que vous êtes sur python 3.6 ou supérieur. Les anciennes versions que vous pourriez faire:

genrev.append(df.query('%s == True' % gen)['revenue_adj'].mean())

Vous pouvez également parcourir les colonnes directement au lieu de construire manuellement la liste:

for col in df.columns:
...


0 commentaires

0
votes

Vous pouvez essayer quelque chose comme ça à la place:

action    500.0
comedy    587.5
drama     420.0
dtype: float64

Production:

df = pd.DataFrame({'Revenue':np.arange(100,1001,100),
                   'action':np.random.choice([True, False],10),
                   'comedy':np.random.choice([True, False],10),
                   'drama':np.random.choice([True, False],10)})

df.iloc[:,1:].apply(lambda x: pd.Series(df.loc[x,'Revenue'])).mean()


0 commentaires

0
votes

J'ai mis en place un exemple de base avec deux genres. J'ai créé une liste, genre_mean, qui stockera le genre et ses revenus moyens sous forme de tuple. Si vous cherchez simplement à stocker le revenu moyen, vous pouvez ajuster l'instruction genre_mean.append ().

genre_mean
[('action', 20.0), ('comedy', 20.0)]

et les résultats

movies = pd.DataFrame({"adj_rev": [10,20,30],
                       "action": ["TRUE", "FALSE", "TRUE"],
                       "comedy": ["FALSE", "TRUE", "FALSE"]})

genres = ["action", "comedy"]

genre_mean = []

for g in genres:
    g_mean = movies["adj_rev"][movies[g]=="TRUE"].mean()
    genre_mean.append((g, g_mean))


0 commentaires

1
votes

Bienvenue dans stackoverflow!

Je ne vois pas vraiment la nécessité d'une boucle sur les colonnes. Les boucles sont généralement un moyen inefficace de travailler sur les dataframes pandas et doivent être évitées si possible. Dans cet esprit, je vais proposer une solution différente. Toutes mes excuses si vous avez vraiment besoin de faire une boucle sur les colonnes. Si vous proposez un peu plus de contexte dans votre question sur les raisons pour lesquelles vous avez choisi l'approche que vous avez ... où vous avez déjà regardé et pourquoi cela n'a pas fonctionné ... cela aide souvent les gens à mieux vous donner plus réponses pertinentes.

Voici comment je le ferais ... sans boucle.

import pandas as pd
import numpy as np

# mimick something similar to your data
arr = [
    [1.2, True, False, True],
    [2.3, False, True, True],
    [3.4, True, True, False]
]
genres = ['action', 'adventure', 'comedy']
df = pd.DataFrame(arr, columns=['rev'] + genres)

# perform your task
result = df.loc[:, genres]            # take just the genre columns
result = result.astype('int')         # convert boolean to int
result[result == 0] = np.nan          # convert 0's to nulls so they're excluded from the avg
result = result.mul(df.rev, axis=0)   # multiply by your 'rev' column
result = result.mean(axis=0)          # calc mean for all genres simultaneously

result
# action       2.30
# adventure    2.85
# comedy       1.75


1 commentaires

Même si la question demande une boucle, votre réponse est très utile. Éliminer les boucles for à tout prix



1
votes
for column in df:
         print(df[column])

0 commentaires