【问题标题】:numpy rollaxis - how exactly does it work?numpy rollaxis - 它究竟是如何工作的?
【发布时间】:2014-04-30 07:09:07
【问题描述】:

所以我在试验 numpy 并且在 rollaxis 方法中遇到了一个奇怪的 (?) 行为。

In [81]: a = np.ones((4, 3, 2))

In [82]: a.shape
Out[82]: (4, 3, 2)

In [83]: x = np.rollaxis(a, 2)

In [84]: x.shape
Out[84]: (2, 4, 3)

In [85]: np.rollaxis(x, -2).shape
Out[85]: (4, 2, 3)

-2 不应该反转滚动轴吗?我想要做的是应用一个只能在 2 坐标是第一个时应用的矩阵。但后来我想把我的数组放回原来的形式。我发现唯一有效的方法是两次应用np.rollaxis(x, 2),或应用np.rollaxis(x, 0, start=3)。我只是通过猜测找到了这些,我不知道它们为什么起作用。他们似乎也掩盖了我真正想做的事情。有人可以解释一下我应该“反转”一卷的方式,或者我做错了什么吗?

(有pythonic的方法吗?)

【问题讨论】:

  • 了解np.rollaxis 的工作原理可能很有见地,但让我告诉你——最好忘记它并立即学习np.moveaxis(这个更好的版本)。例如:np.moveaxis(a, 0, 3) 将第一个维度移动到第四个维度。这相当于np.rollaxis(a, 0, 4)。反向操作是 - 相应地:np.moveaxis(a, 3, 0)np.rollaxis(a, 3)np.moveaxis 可以一次更改多个维度。

标签: python numpy


【解决方案1】:

axis==start 和axis == start-1 的结果是一样的

>>>a=np.ones([1, 2, 3, 4, 5, 6])
(1, 2, 3, 4, 5, 6)
>>> np.rollaxis(a, axis=2, start=2).shape
(1, 2, 3, 4, 5, 6)
>>> np.rollaxis(a, axis=2, start=3).shape
(1, 2, 3, 4, 5, 6)

【讨论】:

    【解决方案2】:

    基本思想是它围绕 nd 数组的轴移动。 它把axis参数提到的轴放在start参数提到的位置;发生这种情况时,以下位置的其余轴将向右移动。如果忽略start 参数,它会将提到的轴移动到第一个位置(即它将作为第0轴移动)

    让我们通过一个例子来理解它:

    In [21]: arr = np.ones((3,4,5,6))
    
    In [22]: arr.shape
    Out[22]: (3, 4, 5, 6)
    # here 0th axis is 3, 1st axis is 4, 2nd axis is 5, 3rd axis is 6
    
    # moving `3`rd axis as `1`st axis
    In [27]: np.rollaxis(arr, 3, 1).shape
    
    # see how `6` which was the third axis has been moved to location `1`
    Out[27]: (3, 6, 4, 5)
    

    在移动轴时(或按 NumPy 的说法滚动),该位置中已经存在的轴为传入轴腾出空间,并且该轴和后面的轴作为一个块向右侧移动。

    如果忽略start参数,axis参数中的轴将被移动到前面(即第0个位置)。

    In [29]: a.shape
    Out[29]: (3, 4, 5, 6)
    
    # ignoring the `start` moves the axis to the very front position.
    In [30]: np.rollaxis(arr, 3).shape
    Out[30]: (6, 3, 4, 5)
    

    np.moveaxis

    比较
    In [38]: arr.shape
    Out[38]: (3, 4, 5, 6)
    
    In [39]: np.rollaxis(arr, 0, -1).shape
    Out[39]: (4, 5, 3, 6)
    
    In [40]: np.moveaxis(arr, 0, -1).shape
    Out[40]: (4, 5, 6, 3)
    

    在上面的例子中观察np.moveaxis 是如何进行循环移位的,而np.rollaxis 只是延伸 仅向右侧。


    PS:另外,请注意,此 rollaxis 操作返回从 NumPy 1.10.0

    开始的输入数组的视图

    【讨论】:

      【解决方案3】:

      方法rollaxis

      def rollaxis(a, axis, start=0):
      

      start“位置”重新分配选定的axis

      按照你的例子:

      a = np.ones((4, 3, 2))
      x = np.rollaxis(a, 2)
      # x.shape = (2, 4, 3)
      

      关于形状:rollaxis 会将您最后一个axis=2 中的数字2 带到第一个位置,因为start=0

      通过使用

      x2 = np.rollaxis(x, -2)
      # x2.shape = (4,2,3)
      

      rollaxis 将带来数字 4,即倒数第二个轴,axis=-2,并在第一个位置重新分配,因为start=0。这解释了你的结果(4,2,3),而不是(4,3,2)

      遵循相同的逻辑,这解释了为什么应用 rollaxis(a,2) 两次会使数组形状恢复到初始形状。 np.rollaxis(x, 0, start=3) 也有效,因为第一个轴转到最后一个,换句话说,(2,4,3) 中的数字 2 转到最后一个位置,结果是 (4,3,2)。

      【讨论】:

      • 所以简单回顾一下:要反转rollaxis(x,n) 的效果,请使用rollaxis(x,0,n+1)
      • 倒数使用 n+1 而不是 n,因为“轴滚动直到它位于 之前这个位置。” (引用:文档)。
      【解决方案4】:

      np.rollaxis(tensor,axis,start) 将axis参数指定的轴毫无例外地移动到位于start的轴之前的位置。

      假设轴是 (1, 2, 3, 4, 5, 6) 如果轴指向 3,并且起点指向 5,那么在滚动之后,3 将在 5 之前。由于在我的示例中,3 位于维度元组的位置 2,axis=2。此外,由于 5 在位置 4,因此 start=4。

      像这样:

      >>> a.shape
      
      (1, 2, 3, 4, 5, 6)
      
      >>> np.rollaxis(a, 2, 4).shape
      
      (1, 2, 4, 3, 5, 6)
      

      如您所见,3 现在正好在 5 之前。 注意: 3 不会移动到位置 4,而是移动到最初位于位置 4 的值之前的位置(在这种情况下结果是位置 3)。

      负数指定位置,就像它们为列表所做的那样。换句话说,axis=-1 指定最后一个位置。在我上面的示例中,-1 位置有一个 6,-2 位置有一个 5。轴和起点都可能是负数。

      你可以像上面那样用负数做同样的事情:

      >>> a.shape
      
      (1, 2, 3, 4, 5, 6)
      
      >>> np.rollaxis(a, -4, -2).shape
      
      (1, 2, 4, 3, 5, 6)
      

      如果没有指定start,则默认为0,即第一个位置。也就是说,如果不指定start,则指定的轴会一直移动到开始位置,也就是原来位置0的1之前。

      如果这令人困惑,这里还有另一种解释可能更有意义: Reason why numpy rollaxis is so confusing?

      【讨论】:

      • 如何将指定的轴带到最后一个位置? np.rollaxis(a,1,len(a.shape)) 可以解决问题,但它看起来像个黑客。
      • axis 需要在[-len(a.shape), len(a.shape)-1](含)和start [-len(a.shape), len(a.shape)](含)范围内,所以这里没有破解。
      • *** 这会将第二个轴移动到末尾 *** >>> import numpy as np; >>> a = np.ones((1,2,3,4,5)); >>> a.shape; (1, 2, 3, 4, 5) >>> np.rollaxis(a, 1, 5).shape; (1, 3, 4, 5, 2)
      猜你喜欢
      • 1970-01-01
      • 2020-05-16
      • 1970-01-01
      • 1970-01-01
      • 2020-06-04
      • 2016-02-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-26
      相关资源
      最近更新 更多