我有一个矩阵(2d numpy ndarray,准确地说):
A = np.array([[4, 0, 0],
[1, 2, 3],
[0, 0, 5]])
我想根据另一个数组中的滚动值独立地滚动A
的每一行:
r = np.array([2, 0, -1])
也就是说,我想这样做:
print np.array([np.roll(row, x) for row,x in zip(A, r)])
[[0 0 4]
[1 2 3]
[0 5 0]]
有没有一种方法可以有效地做到这一点?也许使用花哨的索引技巧?
6条答案
按热度按时间dojqjjoe1#
你可以使用高级索引。它是否是最快的方法可能取决于数组的大小。例如,对于大行,这可能比其他方法慢。
kxxlusnw2#
numpy.lib.stride_tricks.as_strided
stricks(焦v双关语)再次!说到 * 花哨的索引技巧 *,有 * 臭名昭著 * -
np.lib.stride_tricks.as_strided
。这个想法/技巧是从第一列开始得到一个切片部分,直到倒数第二列,并在最后连接。这确保了我们可以根据需要向前迈进,以利用np.lib.stride_tricks.as_strided
,从而避免实际回滚的需要。这就是整个想法!现在,在实际实现方面,我们将使用
scikit-image's view_as_windows
来优雅地使用np.lib.stride_tricks.as_strided
。因此,最终的实现将是-这里有一个样本运行-
对标
让我们对具有大量行和列的阵列进行一些基准测试-
hzbexzde3#
如果你想要更一般的解决方案(处理任何形状和任何轴),我修改了@seberg的解决方案:
taor4pac4#
通过使用快速傅里叶变换,我们可以在频域中应用变换,然后使用逆快速傅里叶变换来获得行移位。
所以这是一个纯numpy的解决方案,只需要一行:
这将应用左移,但我们可以简单地否定指数指数将函数转换为右移函数:
它可以这样使用:
2nc8po8w5#
我实现了一个纯
numpy.lib.stride_tricks.as_strided
解决方案,如下所示sf6xfgos6#
基于divakar的优秀答案,您可以轻松地将此逻辑应用于3D数组(这是我首先来到这里的问题)。这里有一个例子-基本上是扁平化您的数据,滚动它并在以下情况下重塑它:
Divakar的回答并没有公正地说明这在大型数据立方体上的效率有多高。我已经在一个400 x400 x2000的数据格式为int 8的时间。一个等价的for循环大约需要5.5秒,Seberg的答案大约需要3.0秒,而strided_indexing.~ 0.5秒。