假设我有
arr = np.arange(6)
arr
array([0, 1, 2, 3, 4, 5])
我决定将数组视为“像圆圈”:当我最后用完材料时,我想再次从索引0开始。也就是说,我想要一种从索引x
开始选择i
元素的便捷方式。
现在,如果x == 6
,我可以做到
i = 3
np.hstack((arr[i:], arr[:i]))
Out[9]: array([3, 4, 5, 0, 1, 2])
但有没有一种方便的方法可以做到这一点,即使是x > 6
,也不必手动分开阵列并思考逻辑?
例如:
print(roll_array_arround(arr)[2:17])
应该返回。
array([2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0])
答案 0 :(得分:2)
模数运算似乎最合适 -
def rolling_array(n, x, i):
# n is rolling period
# x is length of array
# i is starting number
return np.mod(np.arange(i,i+x),n)
样品运行 -
In [61]: rolling_array(n=6, x=6, i=3)
Out[61]: array([3, 4, 5, 0, 1, 2])
In [62]: rolling_array(n=6, x=17, i=2)
Out[62]: array([2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0])
答案 1 :(得分:2)
请参阅ndarray.take中的mode ='wrap':
https://docs.scipy.org/doc/numpy/reference/generated/numpy.take.html
采取您的假设功能:
print(roll_array_arround(arr)[2:17])
如果隐含它是你所追求的原始数组的真正切片,那就不会发生;包裹的数组不能表示为原始的跨步视图;因此,如果您寻找将ndarray映射到ndarray的函数,则必然会涉及您的数据副本。
也就是说,效率方面,你不应该期望找到与下面的表达式在性能上有显着差异的解决方案。
print(arr.take(np.arange(2,17), mode='wrap'))
答案 2 :(得分:1)
您可以查看的解决方案可能是:
from itertools import cycle
list_to_rotate = np.array([1,2,3,4,5])
rotatable_list = cycle(list_to_rotate)
答案 3 :(得分:-1)
您需要roll
您的阵列。
>>> x = np.arange(10)
>>> np.roll(x, 2)
array([8, 9, 0, 1, 2, 3, 4, 5, 6, 7])
有关详细信息,请参阅numpy documentation。