Tho*_*wne 8 python arrays numpy dataframe pandas
Pandas似乎缺少一个R风格的矩阵级滚动窗口函数(rollapply(..., by.column = FALSE)
),只提供基于矢量的版本.因此,我尝试遵循这个问题,并且它可以复制的示例很好地工作,但DataFrame
即使使用(看似相同的)底层Numpy数组,它也无法与pandas一起使用.
人工问题复制:
import numpy as np
import pandas as pd
from numpy.lib.stride_tricks import as_strided
test = [[x * y for x in range(1, 10)] for y in [10**z for z in range(5)]]
mm = np.array(test, dtype = np.int64)
pp = pd.DataFrame(test).values
Run Code Online (Sandbox Code Playgroud)
mm
和pp
外观是相同的:
numpy直接派生矩阵给了我我想要的完美:
as_strided(mm, (mm.shape[0] - 3 + 1, 3, mm.shape[1]), (mm.shape[1] * 8, mm.shape[1] * 8, 8))
Run Code Online (Sandbox Code Playgroud)
也就是说,它在3d矩阵中给出了3个步幅,每个3行,允许我对一次向下移动一行的子矩阵执行计算.
但是熊猫派生的版本(相同的调用mm
替换为pp
):
as_strided(pp, (pp.shape[0] - 3 + 1, 3, pp.shape[1]), (pp.shape[1] * 8, pp.shape[1] * 8, 8))
Run Code Online (Sandbox Code Playgroud)
就像它以某种方式转换一样奇怪.这与列/行主要订单有关吗?
我需要在Pandas中做矩阵滑动窗口,这似乎是我最好的镜头,特别是因为它真的很快.这里发生了什么?如何让底层的Pandas数组表现得像Numpy?
Ale*_*ley 12
似乎.values
以Fortran顺序返回基础数据(如您推测的那样):
>>> mm.flags # NumPy array
C_CONTIGUOUS : True
F_CONTIGUOUS : False
...
>>> pp.flags # array from DataFrame
C_CONTIGUOUS : False
F_CONTIGUOUS : True
...
Run Code Online (Sandbox Code Playgroud)
这种混淆使得as_strided
数据在内存中以C顺序排列.
要解决问题,您可以按C顺序复制数据并使用与问题相同的步幅:
pp = pp.copy('C')
Run Code Online (Sandbox Code Playgroud)
或者,如果要避免复制大量数据,请调整步幅以确认数据的列顺序布局:
as_strided(pp, (pp.shape[0] - 3 + 1, 3, pp.shape[1]), (8, 8, pp.shape[0]*8))
Run Code Online (Sandbox Code Playgroud)