Jak iterować po kolumnach ramki danych pand, aby uruchomić regresję

187

Jestem pewien, że jest to proste, ale jako kompletny nowicjusz w pythonie mam problem z ustaleniem, jak iterować zmienne w pandasramce danych i uruchomić regresję dla każdej z nich.

Oto co robię:

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()

Wiem, że mogę przeprowadzić taką regresję:

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

ale przypuśćmy, że chcę to zrobić dla każdej kolumny w ramce danych. W szczególności chcę zresetować FIUIX na FSTMX, a następnie FSAIX na FSTMX, a następnie FSAVX na FSTMX. Po każdej regresji chcę przechowywać resztki.

Wypróbowałem różne wersje następujących elementów, ale muszę mieć złą składnię:

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

Myślę, że problem polega na tym, że nie wiem, jak odwoływać się do kolumny zwrotów według klucza, więc returns[k]prawdopodobnie jest źle.

Wszelkie wskazówki dotyczące najlepszego sposobu osiągnięcia tego celu byłyby bardzo mile widziane. Być może brakuje mi wspólnego podejścia do pand.

itzy
źródło
1
Możesz for i in len(df): if i + 1 != len(df): # sm.OLS(returns[returns.coloumns[i]], returns[returns.columns[ i+1]]), fit()
zapisać

Odpowiedzi:

343
for column in df:
    print(df[column])
The Unfun Cat
źródło
1
Wydaje mi się, że zwracam nagłówek kolumny tylko wtedy, gdy używam tej metody. Na przykład: print (df) pokazuje mi dane w kolumnach ramki danych, ale dla cw df: print (c) drukuje tylko nagłówek, a nie dane.
user1761806
5
Ok, zignoruj ​​mnie - drukowałem (kolumna) nie drukowałem (df [kolumna])
user1761806
14
Uważaj na kolumny o tej samej nazwie!
freethebees
4
To miłe i zwięzłe. Spodziewałbym się for x in dfjednak iteracji po wierszach. : - /
Eric Duminil
7
for idx, row in df.iterrows()iteruje po wierszach. Ponieważ operacje oparte na kolumnach są wektoryzowane, naturalne jest, że główna iteracja przebiega nad kolumnami :)
The Unfun Cat
69

Możesz użyć iteritems():

for name, values in df.iteritems():
    print('{name}: {value}'.format(name=name, value=values[0]))
mdh
źródło
33

Ta odpowiedź ma na celu iterację wybranych kolumn, a także wszystkich kolumn w DF.

df.columnsdaje listę zawierającą wszystkie nazwy kolumn w DF. To nie jest bardzo pomocne, jeśli chcesz iterować po wszystkich kolumnach. Ale przydaje się, gdy chcesz iterować tylko wybrane kolumny.

Możemy łatwo używać wycinania list Pythona, aby pokroić df.columns zgodnie z naszymi potrzebami. Na przykład, aby wykonać iterację we wszystkich kolumnach oprócz pierwszej, możemy wykonać:

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

Podobnie do iteracji po wszystkich kolumnach w odwrotnej kolejności, możemy:

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

Możemy iterować wszystkie kolumny na wiele fajnych sposobów, stosując tę ​​technikę. Pamiętaj również, że możesz łatwo uzyskać indeksy wszystkich kolumn, używając:

for ind, column in enumerate(df.columns):
    print(ind, column)
Abhinav Gupta
źródło
21

Możesz indeksować kolumny ramki danych według pozycji za pomocą ix.

df1.ix[:,1]

Zwraca na przykład pierwszą kolumnę. (0 to indeks)

df1.ix[0,]

Zwraca pierwszy wiersz.

df1.ix[:,1]

Byłaby to wartość na przecięciu wiersza 0 i kolumny 1:

df1.ix[0,1]

i tak dalej. Możesz więc enumerate() returns.keys():użyć tego numeru do indeksowania ramki danych.

UKŁUCIE
źródło
8
ixjest przestarzałe, użyjiloc
Yohan Obadia
8

Obejściem tego problemu jest transpozycja DataFramei iteracja po wierszach.

for column_name, column in df.transpose().iterrows():
    print column_name
kdauria
źródło
4
Transpozycja jest raczej droga :)
The Unfun Cat
Może to być drogie, ale jest to świetne rozwiązanie dla stosunkowo małych ramek danych. Dzięki kdauria!
elPastor
5

Korzystając ze zrozumienia listy, możesz uzyskać wszystkie nazwy kolumn (nagłówek):

[column for column in df]

Mehsan
źródło
2
Krótsza wersja: list(df.columns)lub[c for c in df]
The Unfun Cat
4

Na podstawie zaakceptowanej odpowiedzi , jeśli pożądany jest również indeks odpowiadający każdej kolumnie :

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

Powyższy df[column]typ to Series, który można po prostu przekonwertować na numpy ndarrays:

for i, column in enumerate(df):
    print i, np.asarray(df[column])
Bezpłatny inżynier Herpes
źródło
3

Jestem trochę spóźniony, ale oto jak to zrobiłem. Kroki:

  1. Utwórz listę wszystkich kolumn
  2. Użyj itertools, aby wziąć x kombinacji
  3. Dołącz każdą wartość R podniesioną do kwadratu do wynikowej ramki danych wraz z wykluczoną listą kolumn
  4. Posortuj wynik DF w porządku malejącym R do kwadratu, aby zobaczyć, które jest najlepsze dopasowanie.

To jest kod, którego użyłem na DataFrame o nazwie aft_tmt. Ekstrapoluj do swojego przypadku użycia.

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)
Gauraw
źródło