パンダのデータフレームの列を反復して回帰を実行する方法


187

これは簡単だと確信していますが、Pythonの完全な初心者として、pandasデータフレーム内の変数を反復処理し、それぞれで回帰を実行する方法を理解するのに苦労しています。

これが私がやっていることです:

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

私はこのような回帰を実行できることを知っています:

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

データフレームの列ごとにこれを実行するとします。特に、FSTMXでFIUIX、次にFSTMXでFSAIX、FSTMXでFSAVXに回帰したいと思います。各回帰の後、残差を保存します。

以下のさまざまなバージョンを試しましたが、構文が間違っているに違いありません。

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

問題は、キーで返品列を参照する方法がわからないことだと思うのでreturns[k]、おそらく間違っています。

これを行うための最良の方法についてのガイダンスは大歓迎です。おそらく、私が見逃している一般的なパンダのアプローチがあるでしょう。


1
次のようにcolsに添え字を付けることができます。osのfor i in len(df): if i + 1 != len(df): # sm.OLS(returns[returns.coloumns[i]], returns[returns.columns[ i+1]]), fit()類似
EdChum

回答:


343
for column in df:
    print(df[column])

1
このメソッドを使用すると、列ヘッダーのみが返されるようです。したがって、たとえば、print(df)はデータフレーム列のデータを表示しますが、dfのcの場合:print(c)はヘッダーを印刷するだけで、データは印刷しません。
user1761806 2017年

5
Ok ignore
me-

14
同じ名前の列に注意してください!
freethebees 2017

4
それは素晴らしくて簡潔です。for x in dfただし、行を反復処理することを期待します。:-/
エリックドゥミニル2018年

7
for idx, row in df.iterrows()行を反復します。colbased操作はベクトル化されているので、メインの反復は列に対して行われるのが自然です:)
Unfun Cat

69

使用できますiteritems()

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

33

この答えは、DF内のすべての列だけでなく、選択された列を反復することです。

df.columnsDF内のすべての列の名前を含むリストを提供します。すべての列を反復処理する場合、これはあまり役に立ちません。ただし、選択した列のみを反復処理する場合に便利です。

Pythonのリストスライスを簡単に使用して、必要に応じてdf.columnsをスライスできます。たとえば、最初の列を除くすべての列を反復処理するには、次のようにします。

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

同様に、すべての列を逆の順序で反復するのと同じようにできます。

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

この手法を使用すると、さまざまな方法ですべての列を反復処理できます。また、次のコマンドを使用すると、すべての列のインデックスを簡単に取得できます。

for ind, column in enumerate(df.columns):
    print(ind, column)

21

を使用して、位置によってデータフレーム列にインデックスを付けることができますix

df1.ix[:,1]

たとえば、これは最初の列を返します。(0がインデックスになります)

df1.ix[0,]

これは最初の行を返します。

df1.ix[:,1]

これは、行0と列1の交点の値になります。

df1.ix[0,1]

等々。したがってenumerate() returns.keys():、データフレームにインデックスを付けるために番号を使用できます。


8
ixは非推奨です。使用してくださいiloc
Yohan Obadia

8

回避策は、を転置DataFrameし、行を反復処理することです。

for column_name, column in df.transpose().iterrows():
    print column_name

4
移調はかなり高価です:)
Unfun Cat '23

高価になる可能性がありますが、これは比較的小さなデータフレームの優れたソリューションです。kdauriaさん、ありがとう!
elPastor

5

リスト内包表記を使用すると、すべての列名(ヘッダー)を取得できます。

[column for column in df]


2
短いバージョン:list(df.columns)または[c for c in df]
Unfun Cat


3

私は少し遅れましたが、これは私がこれをした方法です。手順:

  1. すべての列のリストを作成する
  2. itertoolsを使用してxの組み合わせを取る
  3. 各結果R二乗値を、除外された列リストと共に結果データフレームに追加します
  4. 結果のDFをRの2乗の降順で並べ替え、どちらが最適かを確認します。

これは、DataFrameで使用したと呼ばれるコードaft_tmtです。ユースケースを自由に推定してください。

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)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.