滚动阵列

时间:2018-04-12 08:06:15

标签: python arrays numpy

假设我有

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])

4 个答案:

答案 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