Comment parcourir des colonnes de pandas dataframe pour exécuter une régression

187

Je suis sûr que c'est simple, mais en tant que novice complet en python, j'ai du mal à comprendre comment itérer sur des variables dans un pandasdataframe et exécuter une régression avec chacune.

Voici ce que je fais:

all_data = {}
for ticker in ['FIUIX', 'FSAIX', 'FSAVX', 'FSTMX']:
    all_data[ticker] = web.get_data_yahoo(ticker, '1/1/2010', '1/1/2015')

prices = DataFrame({tic: data['Adj Close'] for tic, data in all_data.iteritems()})  
returns = prices.pct_change()

Je sais que je peux exécuter une régression comme celle-ci:

regs = sm.OLS(returns.FIUIX,returns.FSTMX).fit()

mais supposons que je veuille le faire pour chaque colonne du dataframe. En particulier, je veux régresser FIUIX sur FSTMX, puis FSAIX sur FSTMX, puis FSAVX sur FSTMX. Après chaque régression, je souhaite stocker les résidus.

J'ai essayé différentes versions de ce qui suit, mais je dois me tromper dans la syntaxe:

resids = {}
for k in returns.keys():
    reg = sm.OLS(returns[k],returns.FSTMX).fit()
    resids[k] = reg.resid

Je pense que le problème est que je ne sais pas comment faire référence aux retours colonne par clé, donc returns[k]c'est probablement faux.

Toute orientation sur la meilleure façon de procéder serait très appréciée. Il me manque peut-être une approche commune aux pandas.

itzy
la source
1
Vous pouvez indiquer les cols comme for i in len(df): if i + 1 != len(df): # sm.OLS(returns[returns.coloumns[i]], returns[returns.columns[ i+1]]), fit()
suit

Réponses:

343
for column in df:
    print(df[column])
Le chat impertinent
la source
1
Il semble que je ne récupère l'en-tête de colonne que lorsque j'utilise cette méthode. Ainsi par exemple: print (df) me montre les données dans les colonnes dataframe mais pour c dans df: print (c) imprime uniquement l'en-tête et non les données.
user1761806
5
Ok ignore-moi - je faisais impression (colonne) pas impression (df [colonne])
user1761806
14
Attention aux colonnes du même nom!
freethebees
4
C'est joli et concis. Je m'attendrais cependant for x in dfà parcourir les lignes. : - /
Eric Duminil
7
for idx, row in df.iterrows()itère sur les lignes. Étant donné que les opérations basées sur col sont vectorisées, il est naturel que l'itération principale soit sur les colonnes :)
The Unfun Cat
69

Vous pouvez utiliser iteritems():

for name, values in df.iteritems():
    print('{name}: {value}'.format(name=name, value=values[0]))
mdh
la source
33

Cette réponse consiste à parcourir les colonnes sélectionnées ainsi que toutes les colonnes d'un DF.

df.columnsdonne une liste contenant tous les noms de colonnes dans le DF. Maintenant, ce n'est pas très utile si vous voulez parcourir toutes les colonnes. Mais cela est pratique lorsque vous souhaitez parcourir uniquement les colonnes de votre choix.

Nous pouvons facilement utiliser le découpage de liste de Python pour découper les df.columns en fonction de nos besoins. Par exemple, pour parcourir toutes les colonnes sauf la première, nous pouvons faire:

for column in df.columns[1:]:
    print(df[column])

De même pour parcourir toutes les colonnes dans l'ordre inverse, nous pouvons faire:

for column in df.columns[::-1]:
    print(df[column])

Nous pouvons parcourir toutes les colonnes de nombreuses manières intéressantes en utilisant cette technique. N'oubliez pas que vous pouvez facilement obtenir les indices de toutes les colonnes en utilisant:

for ind, column in enumerate(df.columns):
    print(ind, column)
Abhinav Gupta
la source
21

Vous pouvez indexer les colonnes de dataframe en fonction de la position à l'aide de ix.

df1.ix[:,1]

Cela renvoie la première colonne par exemple. (0 serait l'indice)

df1.ix[0,]

Cela renvoie la première ligne.

df1.ix[:,1]

Ce serait la valeur à l'intersection de la ligne 0 et de la colonne 1:

df1.ix[0,1]

etc. Vous pouvez donc enumerate() returns.keys():et utiliser le nombre pour indexer la trame de données.

COUP
la source
8
ixest obsolète, utiliseziloc
Yohan Obadia
8

Une solution de contournement consiste à transposer DataFrameet à itérer sur les lignes.

for column_name, column in df.transpose().iterrows():
    print column_name
kdauria
la source
4
La transposition est assez chère :)
The Unfun Cat
Cela peut être cher, mais c'est une excellente solution pour les dataframes relativement petites. Merci kdauria!
elPastor le
5

En utilisant la compréhension de liste, vous pouvez obtenir tous les noms de colonnes (en-tête):

[column for column in df]

MEhsan
la source
2
Version plus courte: list(df.columns)ou[c for c in df]
The Unfun Cat
4

En fonction de la réponse acceptée , si un index correspondant à chaque colonne est également souhaité :

for i, column in enumerate(df):
    print i, df[column]

Le df[column]type ci-dessus est Series, qui peut simplement être converti en numpy ndarrays:

for i, column in enumerate(df):
    print i, np.asarray(df[column])
Ingénieur sans herpès
la source
3

Je suis un peu en retard mais voici comment je l'ai fait. Les marches:

  1. Créer une liste de toutes les colonnes
  2. Utilisez itertools pour prendre x combinaisons
  3. Ajouter chaque valeur R au carré du résultat à une trame de données de résultat avec la liste des colonnes exclues
  4. Triez le résultat DF par ordre décroissant de R au carré pour voir quel est le meilleur ajustement.

C'est le code que j'ai utilisé sur DataFrame appelé aft_tmt. N'hésitez pas à extrapoler à votre cas d'utilisation.

import pandas as pd
# setting options to print without truncating output
pd.set_option('display.max_columns', None)
pd.set_option('display.max_colwidth', None)

import statsmodels.formula.api as smf
import itertools

# This section gets the column names of the DF and removes some columns which I don't want to use as predictors.
itercols = aft_tmt.columns.tolist()
itercols.remove("sc97")
itercols.remove("sc")
itercols.remove("grc")
itercols.remove("grc97")
print itercols
len(itercols)

# results DF
regression_res = pd.DataFrame(columns = ["Rsq", "predictors", "excluded"])

# excluded cols
exc = []

# change 9 to the number of columns you want to combine from N columns.
#Possibly run an outer loop from 0 to N/2?
for x in itertools.combinations(itercols, 9):
    lmstr = "+".join(x)
    m = smf.ols(formula = "sc ~ " + lmstr, data = aft_tmt)
    f = m.fit()
    exc = [item for item in x if item not in itercols]
    regression_res = regression_res.append(pd.DataFrame([[f.rsquared, lmstr, "+".join([y for y in itercols if y not in list(x)])]], columns = ["Rsq", "predictors", "excluded"]))

regression_res.sort_values(by="Rsq", ascending = False)
Gaurav
la source