有没有办法在Numpy中有效地实现1D阵列的滚动窗口?
例如,我有这个纯Python代码片段来计算1D列表的滚动标准偏差,其中observations是1D值列表,并且n是标准差的窗口长度:
stdev = []
for i, data in enumerate(observations[n-1:]):
strip = observations[i:i+n]
mean = sum(strip) / n
stdev.append(sqrt(250*sum([(s-mean)**2 for s in strip])/(n-1)))
Run Code Online (Sandbox Code Playgroud)
有没有办法在Numpy中完全执行此操作,即没有任何Python循环?标准偏差是微不足道的numpy.std,但滚动窗口部分完全残留我.
我发现这篇关于Numpy滚动窗口的博文,但它似乎不适用于1D阵列.
在Python或NumPy中,找出第一次出现的子阵列的最佳方法是什么?
例如,我有
a = [1, 2, 3, 4, 5, 6]
b = [2, 3, 4]
Run Code Online (Sandbox Code Playgroud)
找出b出现在哪里的最快方法(运行时间)是什么?我理解字符串这非常容易,但对于列表或numpy ndarray呢?
非常感谢!
[编辑]我更喜欢numpy解决方案,因为从我的经验来看,numpy矢量化比Python列表理解要快得多.同时,大数组是巨大的,所以我不想把它转换成字符串; 这将是(太长).
问:如何加快速度?
下面是我对Matlab的im2col '滑动'的实现,以及返回每个第n列的附加功能.该函数采用图像(或任意2个暗淡的数组)并从左到右,从上到下滑动,拾取给定大小的每个重叠子图像,并返回其列为子图像的数组.
import numpy as np
def im2col_sliding(image, block_size, skip=1):
rows, cols = image.shape
horz_blocks = cols - block_size[1] + 1
vert_blocks = rows - block_size[0] + 1
output_vectors = np.zeros((block_size[0] * block_size[1], horz_blocks * vert_blocks))
itr = 0
for v_b in xrange(vert_blocks):
for h_b in xrange(horz_blocks):
output_vectors[:, itr] = image[v_b: v_b + block_size[0], h_b: h_b + block_size[1]].ravel()
itr += 1
return output_vectors[:, ::skip]
Run Code Online (Sandbox Code Playgroud)
例:
a = np.arange(16).reshape(4, 4)
print a
print im2col_sliding(a, (2, 2)) # return every …Run Code Online (Sandbox Code Playgroud) 是否有任何便利工具在Numpy阵列上进行块运算?
我正在考虑像Ising自旋重整化这样的操作,其中将矩阵划分为块并返回矩阵,其中每个块由其和,平均或其他函数替换.
我有大约100,000个二维数组,我需要应用本地过滤器.两个尺寸均匀,窗口超过2x2,进一步移动2个,因此每个元素都在一个窗口中.输出是相同大小的二进制二维数组,我的过滤器也是二进制2x2.我的过滤器的0部分将映射到0,我的过滤器的部分为1,如果它们具有相同的值则全部映射到1,如果它们不完全相同则映射到0.这是一个例子:
Filter: 0 1 Array to filter: 1 2 3 2 Output: 0 1 0 0
1 0 2 3 3 3 1 0 0 0
Run Code Online (Sandbox Code Playgroud)
当然,我可以使用double for循环来做到这一点,但这是非常低效的,并且必须有更好的方法.我读到这个:在numpy上的二维数组上的矢量化移动窗口但是我不确定我将如何应用于我的情况.
我意识到我的问题与numpy中的2D数组上的矢量化移动窗口 非常相似,但那里的答案并不能完全满足我的需求.
是否可以进行包含所谓边缘效应的矢量化2D移动窗口(滚动窗口)?最有效的方法是什么?
也就是说,我想将移动窗口的中心滑过我的网格,这样中心就可以在网格中的每个单元格上移动.沿着网格的边缘移动时,此操作将仅返回与网格重叠的窗口部分.如果窗口完全位于网格内,则返回完整窗口.例如,如果我有网格:
array([[1,2,3,4],
[2,3,4,5],
[3,4,5,6],
[4,5,6,7]])
Run Code Online (Sandbox Code Playgroud)
...并且我想使用3x3以该点为中心的窗口对该网格中的每个点进行采样,该操作应返回一系列数组,或者理想情况下,返回原始数组中的一系列视图,如下所示:
array([[1,2], array([[1,2,3], array([[2,3,4], array([[3,4],
[2,3]]) [2,3,4]]) [3,4,5]]) [4,5]])
array([[1,2], array([[1,2,3], array([[2,3,4], array([[3,4],
[2,3], [2,3,4], [3,4,5], [4,5],
[3,4]]) [3,4,5]]) [4,5,6]]) [5,6]])
array([[2,3], array([[2,3,4], array([[3,4,5], array([[4,5],
[3,4], [3,4,5], [4,5,6], [5,6],
[4,5]]) [4,5,6]]) [5,6,7]]) [6,7]])
array([[3,4], array([[3,4,5], array([[4,5,6], array([[5,6],
[4,5]]) [4,5,6]]) [5,6,7]]) [6,7]])
Run Code Online (Sandbox Code Playgroud)
因为我需要多次执行此操作,速度很重要,理想的解决方案是矢量化操作.