首页 > 解决方案 > 使用 numpy.roll 将数组移动到特殊位置

问题描述

我有一个 256x256 数组,我想使用特殊的行和列向右移动。我正在使用 numpy.roll 来实现它。如果我使用以下代码,则 shift 是向右的一列。

import cv2
import matplotlib.pyplot as plt
import numpy as np

# Input (256x256 0 values array)
array = np.zeros((256,256))

# Draw a square inside the array (1 values)
array[100:156,100:156] = 1

# Shift the square to the right (1 as shift value)
shifted_array = np.roll(array,1)

如果我无限重复该过程,它会在数组的整个宽度(256 列)上移动,然后重新启动。我想要做的是将数组从第 120 列移到第 130 列。这意味着最大移位为 10 列(而不是像以前那样的 256 列)。我怎样才能做到这一点?

[已解决] 最后,我找到了一种使用以下代码实现此目的的方法:

import cv2
import matplotlib.pyplot as plt
import numpy as np

# Input (256x256 0 values array)
array = np.zeros((256,256))

# Draw a square inside the array (1 values)
array[100:156,100:156] = 1

# Cropping the image between columns 120 and 130
cropped_image = array[:,120:130]

# Loop to shift the image every column and get the original dimensions  
i = 1
shift_value = 1

while i < len(cropped_image):
    shifted_array = np.roll(cropped_image, shift_value)
    shift_value = shift_value + 1
    i = i + 1
    new_array = np.zeros(array.shape)
    new_array[:,120:130] = shifted_array

标签: pythonarraysnumpyshift

解决方案


上面的while循环没有做任何事情。 array永远不会改变它的状态,所以只有最后的迭代被保存在 shift_array 中。下面使用一个较小的数组来查看结果。

import numpy as np

arr = np.zeros((12,12), dtype=np.int)
arr[ 4:8, 6:10]  = 1
arr
# array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
#        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
#        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
#        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
#        [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0],
#        [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0],
#        [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0],
#        [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0],
#        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
#        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
#        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
#        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])

crop = np.s_[:, 5:11]  # crop is the selection to roll.

new_array = np.zeros_like(arr)
new_array[crop] = np.roll(arr[crop], len(arr)-1)

new_array
# array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
#        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
#        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
#        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
#        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
#        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
#        [0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0],
#        [0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0],
#        [0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0],
#        [0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0],
#        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
#        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])

这具有将正方形向下移动两行并留下一列的效果。

根据您要实现的目标,最好探索使用轴参数来np.roll(arr, 1, axis=1)显式地向左/向右axis=0滚动和/或向上/向下滚动。


推荐阅读