【问题标题】:How do you rotate elements in a 2D numpy array by 'n' units?如何将 2D numpy 数组中的元素旋转“n”个单位?
【发布时间】:2017-05-21 00:41:46
【问题描述】:
x = [[1, 2, 3],
     [4, 5, 6],
     [7, 8, 9]]

旋转 1 个单位应该给出:

x = [[4, 1, 2],
     [7, 5, 3],
     [8, 9, 6]]

基本上,我想将数组中的每个圆形层移动“n”个单位。

我查看了 numpy.roll,但不知道在这个用例中使用它。 我不能使用像 scipy.ndimage.interpolation.rotate 这样的图像旋转例程,因为它们会改变形状并且不能完全达到预期的效果。

编辑:

对于 4 X 4 矩阵:

x = [[a, b, c, d],
     [e, f, g, h],
     [i, j, k, l],
     [m, n, o, p]]

旋转 1 个单位应该给出:

x = [[e, a, b, c],
     [i, j, f, d],
     [m, k, g, h],
     [n, o, p, l]]

编辑:

添加一些关于这如何适用于任意尺寸的说明。

对于旋转 1 个单位的 N X N 矩阵,外部“环”首先移动 1。其余的“内部”(N-2) X (N-2) 矩阵递归遵循相同的逻辑。

【问题讨论】:

  • 我不熟悉 numpy 但数组 rotation 是否应该影响其中的元素?因为您在原始数组中有 9 但在旋转版本中没有。我真的不确定,只是问一下,以防它可能是错误的。
  • 能否也展示一个 4x4 数组的示例?
  • 你能检查你的结果吗?它应该是[[4, 1, 2], [7, 5, 3], [8, 9, 6]] 吗?因为现在,我无法理解它......
  • 你是对的。不知道我是怎么搞砸的。固定。
  • 编辑添加 4 X 4 案例

标签: python arrays numpy


【解决方案1】:

这是一种方法,假设您希望旋转以使切片之间的移位量保持不变,其中切片是指从中心向外指向的最外层元素 -

def outer_slice(x):
    return np.r_[x[0],x[1:-1,-1],x[-1,:0:-1],x[-1:0:-1,0]]

def rotate_steps(x, shift):
    out = np.empty_like(x)
    N = x.shape[0]
    idx = np.arange(x.size).reshape(x.shape)
    for n in range((N+1)//2):
        sliced_idx = outer_slice(idx[n:N-n,n:N-n])
        out.ravel()[sliced_idx] = np.roll(np.take(x,sliced_idx), shift)
    return out

样本运行

案例 #1(3 x 3 阵列):

In [444]: x
Out[444]: 
array([[24, 85, 97],
       [51, 33, 11],
       [86, 38, 33]])

In [445]: rotate_steps(x,shift=1)
Out[445]: 
array([[51, 24, 85],
       [86, 33, 97],
       [38, 33, 11]])

案例 #2(4 x 4 阵列):

In [447]: x
Out[447]: 
array([[11, 70, 28, 13],
       [44, 41, 17, 82],
       [47, 32, 89, 25],
       [32, 20, 67, 98]])

In [448]: rotate_steps(x,shift=1)
Out[448]: 
array([[44, 11, 70, 28],
       [47, 32, 41, 13],
       [32, 89, 17, 82],
       [20, 67, 98, 25]])

In [449]: rotate_steps(x,shift=2)
Out[449]: 
array([[47, 44, 11, 70],
       [32, 89, 32, 28],
       [20, 17, 41, 13],
       [67, 98, 25, 82]])

【讨论】:

    【解决方案2】:

    对于 3x3 数组,您可以使用 np.rollndarray.flat 完成此操作:

    >>> x = np.arange(1, 10).reshape((3, 3))
    >>> x
    array([[1, 2, 3],
           [4, 5, 6],
           [7, 8, 9]])
    >>> i = np.array([0, 1, 2, 5, 8, 7, 6, 3])  # Indices in circular order
    >>> x.flat[i]
    array([1, 2, 3, 6, 9, 8, 7, 4])
    

    旋转 1 个单位:

    >>> x.flat[i] = np.roll(x.flat[i], 1)  # Rotate indices and reassign
    >>> x
    array([[4, 1, 2],
           [7, 5, 3],
           [8, 9, 6]])
    

    旋转 4 个单位:

    >>> x.flat[i] = np.roll(x.flat[i], 4)
    >>> x
    array([[9, 8, 7],
           [6, 5, 4],
           [3, 2, 1]])
    

    对于 4x4 的情况,我仍然需要弄清楚每个“圆”是否需要根据它们的长度以不同的“速度”旋转...

    【讨论】:

    • 这是一个有趣的方法。
    【解决方案3】:

    您正在对矩阵应用排列。排列通常由向量表示,(i-->p[i]),并应用于向量。如果需要,您可以在矩阵中表示矩阵的排列,排列将是对矩阵,因此 (i,j) 处的元素移动到 m[i,j] 。

    构建矩阵后,只需一个简单的循环即可应用排列。

    【讨论】:

    • 我相信这也是@Praveen 的想法。
    猜你喜欢
    • 1970-01-01
    • 2019-01-11
    • 2012-06-08
    • 2016-07-20
    • 2014-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-18
    相关资源
    最近更新 更多