我有这样一个数组:
A = array([1,2,3,4,5,6,7,8,9,10])
Run Code Online (Sandbox Code Playgroud)
我试图得到这样的数组:
B = array([[1,2,3],
[2,3,4],
[3,4,5],
[4,5,6]])
Run Code Online (Sandbox Code Playgroud)
每行(固定的任意宽度)移动一个.A的数组是10k记录长,我试图在Numpy中找到一种有效的方法.目前我正在使用vstack和一个缓慢的for循环.有更快的方法吗?
编辑:
width = 3 # fixed arbitrary width
length = 10000 # length of A which I wish to use
B = A[0:length + 1]
for i in range (1, length):
B = np.vstack((B, A[i, i + width + 1]))
Run Code Online (Sandbox Code Playgroud) 我最近在这篇文章的答案中学到了大步,并且想知道如何使用它们来比我在本文中提出的更有效地计算移动平均滤波器(使用卷积滤波器).
这就是我到目前为止所拥有的.它接受原始数组的视图然后将其滚动必要的量并将内核值相加以计算平均值.我知道边缘没有正确处理,但我可以在以后处理...有更好更快的方法吗?目标是过滤大到5000x5000 x 16层的大型浮点阵列,这个任务scipy.ndimage.filters.convolve相当慢.
请注意,我正在寻找8邻居连接,即3x3滤镜取9个像素的平均值(焦点像素周围8个),并将该值分配给新图像中的像素.
import numpy, scipy
filtsize = 3
a = numpy.arange(100).reshape((10,10))
b = numpy.lib.stride_tricks.as_strided(a, shape=(a.size,filtsize), strides=(a.itemsize, a.itemsize))
for i in range(0, filtsize-1):
if i > 0:
b += numpy.roll(b, -(pow(filtsize,2)+1)*i, 0)
filtered = (numpy.sum(b, 1) / pow(filtsize,2)).reshape((a.shape[0],a.shape[1]))
scipy.misc.imsave("average.jpg", filtered)
Run Code Online (Sandbox Code Playgroud)
编辑关于我如何看待这个工作的澄清:
当前代码:
我希望的是更好地使用stride_tricks直接获取9个值或内核元素的总和,对于整个数组,或者有人可以说服我另一个更有效的方法......
编写一个计算时间序列最大值的函数非常容易.需要一点思考才能及时写出来O(n)而不是O(n^2)时间.但它并没有那么糟糕.这将有效:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
def max_dd(ser):
max2here = pd.expanding_max(ser)
dd2here = ser - max2here
return dd2here.min()
Run Code Online (Sandbox Code Playgroud)
让我们设置一个简短的系列来试试吧:
np.random.seed(0)
n = 100
s = pd.Series(np.random.randn(n).cumsum())
s.plot()
plt.show()
Run Code Online (Sandbox Code Playgroud)

正如预期的那样,max_dd(s)在-17.6附近显示出一些东西.好,很棒,很棒.现在说我有兴趣计算这个系列的滚动缩幅.即每个步骤,我想计算指定长度的前一个子系列的最大值.这很容易使用pd.rolling_apply.它的工作原理如下:
rolling_dd = pd.rolling_apply(s, 10, max_dd, min_periods=0)
df = pd.concat([s, rolling_dd], axis=1)
df.columns = ['s', 'rol_dd_10']
df.plot()
Run Code Online (Sandbox Code Playgroud)

这非常有效.但感觉很慢.在pandas或其他工具包中是否有一个特别灵活的算法来快速完成这项工作?我开始写一些定制的东西:它跟踪各种中间数据(观察到的最大值的位置,先前发现的下降的位置),以减少许多冗余计算.它确实节省了一些时间,但不是很多,而且几乎没有尽可能多的时间.
我认为这是因为Python/Numpy/Pandas中的所有循环开销.但是我目前在Cython中还不够流利,真正知道如何从这个角度开始攻击它.我希望以前有人试过这个.或者,也许有人可能想看看我的"手工"代码,并愿意帮助我将其转换为Cython.
编辑:对于想要审查这里提到的所有功能(以及其他一些!)的人,请查看iPython笔记本:http://nbviewer.ipython.org/gist/8one6/8506455
它显示了这个问题的一些方法如何相关,检查它们是否给出相同的结果,并显示它们对各种大小的数据的运行时间.
如果有人有兴趣,我在帖子中提到的"定制"算法是rolling_dd_custom.我认为如果在Cython中实现,这可能是一个非常快速的解决方案.
我有一个NumPy数组,[1,2,3,4,5,6,7,8,9,10,11,12,13,14]并希望有一个像这样的数组[[1,2,3,4], [2,3,4,5], [3,4,5,6], ..., [11,12,13,14]].
当然这可以通过循环大数组并将长度为4的数组添加到新数组中,但我很好奇是否有一些秘密的'魔术'Python方法正在做这个:)