小编典典

为什么熊猫滚动使用一维ndarray

python

我的动机是利用熊猫rolling功能来进行滚动多因素回归(这个问题是 不是
关于滚动多因素回归)。我希望我可以apply在a之后使用,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个一维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生成一维ndarray长度的长度window,与我预期ndarray的形状相对(window, len(df.columns))

问题是为什么?

我现在没有办法轻松进行滚动的多因素回归。


阅读 222

收藏
2020-12-20

共1个答案

小编典典

使用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 ]])

在那里有巨大的进步,我希望在大型阵列上能保持明显的进步!

2020-12-20