加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

python – 为什么pandas滚动使用单维ndarray

发布时间:2020-12-20 10:35:08 所属栏目:Python 来源:网络整理
导读:我有动力使用熊猫滚动功能来执行滚动多因素回归(这个问题不是关于滚动多因素回归).我希望我能够在df.rolling(2)之后使用apply并获取生成的pd.DataFrame,用.values提取ndarray并执行必要的矩阵乘法.它没有那么成功. 这是我发现的: import pandas as pdimport
我有动力使用熊猫滚动功能来执行滚动多因素回归(这个问题不是关于滚动多因素回归).我希望我能够在df.rolling(2)之后使用apply并获取生成的pd.DataFrame,用.values提取ndarray并执行必要的矩阵乘法.它没有那么成功.

这是我发现的:

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 – >应用表现如我所料:

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’ object has no attribute ‘values’

好的,所以pandas在其滚动实现中使用了直接的ndarray.我能解决这个问题.不要使用.values来获取ndarray,让我们尝试:

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

shapes (1,) and (2,1) not aligned: 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,)
      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对象.滚动怎么样(2)

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

<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对象.滚动为每列产生一个长度窗口的单维ndarray,而不是我预期的形状ndarray(window,len(df.columns)).

问题是为什么?

我现在没有办法轻松运行滚动多因素回归.

解决方法

使用 strides views concept on dataframe,这是一个矢量化的方法 –

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

运行时测试 –

In [101]: df = pd.DataFrame(np.random.rand(5,'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 ]])

那里有巨大的改进,我希望在更大的阵列上保持显着!

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读