python - Numpy - 一维输入数组的多个 numpy.roll
问题描述
我想返回一个numpy.array
带有多卷给定 1D的 2D numpy.array
。
>>> multiroll(np.arange(10), [-1, 0, 1, 2])
array([[1., 0., 9., 8.],
[2., 1., 0., 9.],
[3., 2., 1., 0.],
[4., 3., 2., 1.],
[5., 4., 3., 2.],
[6., 5., 4., 3.],
[7., 6., 5., 4.],
[8., 7., 6., 5.],
[9., 8., 7., 6.],
[0., 9., 8., 7.]])
是否有 , , 或其他功能的组合numpy.roll
可以numpy.tile
做到numpy.repeat
这一点?
这是我尝试过的
def multiroll(array, rolls):
"""Create multiple rolls of 1D vector"""
m = len(array)
n = len(rolls)
shape = (m, n)
a = np.empty(shape)
for i, roll in enumerate(rolls):
a[:,i] = np.roll(array, roll)
return a
我预计会有一种更“Numpythonic”的方式来做到这一点,它不使用循环。
解决方案
方法#1:为了优雅
这是一种方法broadcasting
-
In [44]: a
Out[44]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
In [45]: rolls
Out[45]: array([-1, 0, 1, 2])
In [46]: a[(np.arange(len(a))[:,None]-rolls) % len(a)]
Out[46]:
array([[1, 0, 9, 8],
[2, 1, 0, 9],
[3, 2, 1, 0],
[4, 3, 2, 1],
[5, 4, 3, 2],
[6, 5, 4, 3],
[7, 6, 5, 4],
[8, 7, 6, 5],
[9, 8, 7, 6],
[0, 9, 8, 7]])
方法#2:为了内存/性能效率
想法主要是从 - 借来的this post
。
我们可以利用np.lib.stride_tricks.as_strided
basedscikit-image's view_as_windows
来获得滑动窗口。有关使用based 的更多信息as_strided
view_as_windows
。
from skimage.util.shape import view_as_windows
def multiroll_stridedview(a, r):
r = np.asarray(r)
# Concatenate with sliced to cover all rolls
a_ext = np.concatenate((a,a[:-1]))
# Get sliding windows; use advanced-indexing to select appropriate ones
n = len(a)
return view_as_windows(a_ext,n)[:,(n-r)%n]
推荐阅读
- javascript - 我试图在某个时间触发此功能,但我不知道为什么不起作用
- python - 改变 Python 中的计算限制
- kotlin - 父类中受保护的内联方法不能访问其他受保护的方法
- javascript - 将 Javascript 对象解析为数组
- python - 将嵌套字典转换为数据框并与另一个数据框连接
- flutter - Flutter中如何维护TabBarView中的页面状态?
- windows - ESENT 内部:JetPrereadKeys() 的预期行为
- r - 在闪亮的部署中,如何解决 adminLTE 部署问题?
- rx-java - take(1) 是否会阻止上游流动的工作?
- javascript - React Redux 没有调度 API 调用来删除播放器