我的动机是利用熊猫rolling功能来进行滚动多因素回归(这个问题是 不是 关于滚动多因素回归)。我希望我可以apply在a之后使用,df.rolling(2)并使用所得结果pd.DataFrame提取ndarray.values并执行必要的矩阵乘法。那样行不通。
rolling
apply
df.rolling(2)
pd.DataFrame
.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,让我们试试:
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个一维ndarray对象。关于什么rolling(2)
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生成一维ndarray长度的长度window,与我预期ndarray的形状相对(window, len(df.columns))。
window
(window, len(df.columns))
我现在没有办法轻松进行滚动的多因素回归。
使用strides views concept ondataframe,这是向量化方法-
strides views concept ondataframe
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 ]])
在那里有巨大的进步,我希望在大型阵列上能保持明显的进步!