17

pandasrolling機能を使用してローリング多要素回帰を実行することにしました (この質問は、ローリング多要素回帰に関するものではありません)。applya の後に使用しdf.rolling(2)て、結果pd.DataFrameの抽出を ndarray で取得し.values、必要な行列乗算を実行できると期待していました。それはうまくいきませんでした。

これが私が見つけたものです:

import pandas as pd
import numpy as np

np.random.seed([3,1415])
df = pd.DataFrame(np.random.rand(5, 2).round(2), columns=['A', 'B'])
X = np.random.rand(2, 1).round(2)

オブジェクトはどのように見えますか:

print "\ndf = \n", df
print "\nX = \n", X
print "\ndf.shape =", df.shape, ", X.shape =", X.shape

df = 
      A     B
0  0.44  0.41
1  0.46  0.47
2  0.46  0.02
3  0.85  0.82
4  0.78  0.76

X = 
[[ 0.93]
 [ 0.83]]

df.shape = (5, 2) , X.shape = (2L, 1L)

行列の乗算は正常に動作します。

df.values.dot(X)

array([[ 0.7495],
       [ 0.8179],
       [ 0.4444],
       [ 1.4711],
       [ 1.3562]])

apply を使用して行ごとの内積を実行すると、期待どおりに動作します。

df.apply(lambda x: x.values.dot(X)[0], axis=1)

0    0.7495
1    0.8179
2    0.4444
3    1.4711
4    1.3562
dtype: float64

Groupby -> Apply は、期待どおりに動作します。

df.groupby(level=0).apply(lambda x: x.values.dot(X)[0, 0])

0    0.7495
1    0.8179
2    0.4444
3    1.4711
4    1.3562
dtype: float64

しかし、私が実行すると:

df.rolling(1).apply(lambda x: x.values.dot(X))

私は得る:

AttributeError: 'numpy.ndarray' オブジェクトに属性 'values' がありません

わかりました、パンダはndarrayそのrolling実装内でまっすぐに使用しています。私はそれを扱うことができます。.valuesを使用して を取得する代わりに、ndarray次を試してみましょう。

df.rolling(1).apply(lambda x: x.dot(X))

形状 (1,) と (2,1) が整列していない: 1 (dim 0) != 2 (dim 0)

待って!何?!

そこで、ローリングが何をしているかを調べるカスタム関数を作成しました。

def print_type_sum(x):
    print type(x), x.shape
    return x.sum()

次に実行しました:

print df.rolling(1).apply(print_type_sum)

<type 'numpy.ndarray'> (1L,)
<type 'numpy.ndarray'> (1L,)
<type 'numpy.ndarray'> (1L,)
<type 'numpy.ndarray'> (1L,)
<type 'numpy.ndarray'> (1L,)
<type 'numpy.ndarray'> (1L,)
<type 'numpy.ndarray'> (1L,)
<type 'numpy.ndarray'> (1L,)
<type 'numpy.ndarray'> (1L,)
<type 'numpy.ndarray'> (1L,)
      A     B
0  0.44  0.41
1  0.46  0.47
2  0.46  0.02
3  0.85  0.82
4  0.78  0.76

私の結果pd.DataFrameは同じです、それは良いです。しかし、10 個の 1 次元ndarrayオブジェクトが出力されました。どうですかrolling(2)

print df.rolling(2).apply(print_type_sum)

<type 'numpy.ndarray'> (2L,)
<type 'numpy.ndarray'> (2L,)
<type 'numpy.ndarray'> (2L,)
<type 'numpy.ndarray'> (2L,)
<type 'numpy.ndarray'> (2L,)
<type 'numpy.ndarray'> (2L,)
<type 'numpy.ndarray'> (2L,)
<type 'numpy.ndarray'> (2L,)
      A     B
0   NaN   NaN
1  0.90  0.88
2  0.92  0.49
3  1.31  0.84
4  1.63  1.58

同じこと、出力を期待しますが、8 つndarrayのオブジェクトを出力しました。 私が期待していた形状とは対照的に、各列の長さrollingの単一次元を生成しています。ndarraywindowndarray(window, len(df.columns))

質問はなぜですか?

ローリング多因子回帰を簡単に実行する方法がありません。

4

4 に答える 4

7

を使用してstrides views concept on dataframe、ここにベクトル化されたアプローチがあります -

get_sliding_window(df, 2).dot(X) # window size = 2

実行時テスト -

In [101]: df = pd.DataFrame(np.random.rand(5, 2).round(2), columns=['A', 'B'])

In [102]: X = np.array([2, 3])

In [103]: rolled_df = roll(df, 2)

In [104]: %timeit rolled_df.apply(lambda df: pd.Series(df.values.dot(X)))
100 loops, best of 3: 5.51 ms per loop

In [105]: %timeit get_sliding_window(df, 2).dot(X)
10000 loops, best of 3: 43.7 µs per loop

結果の検証 -

In [106]: rolled_df.apply(lambda df: pd.Series(df.values.dot(X)))
Out[106]: 
      0     1
1  2.70  4.09
2  4.09  2.52
3  2.52  1.78
4  1.78  3.50

In [107]: get_sliding_window(df, 2).dot(X)
Out[107]: 
array([[ 2.7 ,  4.09],
       [ 4.09,  2.52],
       [ 2.52,  1.78],
       [ 1.78,  3.5 ]])

そこには大きな改善があり、より大きなアレイでも目立つようになることを願っています!

于 2016-12-31T09:09:22.003 に答える