大部分困惑是由人类的直觉导致的-我们如何考虑移动轴。我们可以指定多个滚动步骤(前后两个步骤),或者指定最终形状元组中的位置,或者相对于原始形状的位置。
我认为理解的关键rollaxis
是将注意力放在原始形状的插槽上。我能想到的最一般的说法是:
滚动a.shape[axis]
到之前的位置a.shape[start]
before
在此上下文中与列表中的含义相同insert()
。因此可以在结尾之前插入。
的基本动作rollaxis
是:
axes = list(range(0, n))
axes.remove(axis)
axes.insert(start, axis)
return a.transpose(axes)
如果为axis<start
,则start-=1
说明该remove
操作。
负值获得+=n
,因此rollaxis(a,-2,-3)
与相同np.rollaxis(a,2,1)
。例如a.shape[-3]==a.shape[1]
。Listinsert
还允许插入位置为负数,但rollaxis
不使用该功能。
因此,关键是要了解该remove/insert
对动作并进行了解transpose(x)
。
我怀疑rollaxis
它打算成为的更直观的版本transpose
。是否达到目标是另一个问题。
您建议省略start-=1
或全面申请
省略它不会更改您的2个示例。它只影响rollaxis(a,1,4)
大小写,与when isaxes.insert(4,1)
相同。在仍然放置在端。稍微更改一下测试:axes.insert(3,1)``axes``[0,2,3]``1
np.rollaxis(a,1,3).shape
# (3, 5, 4, 6) # a.shape[1](4) placed before a.shape[3](6)
没有 -=1
# transpose axes == [0, 2, 3, 1]
# (3, 5, 6, 4) # the 4 is placed at the end, after 6
如果相反-=1
总是适用
np.rollaxis(a,3,1).shape
# (3, 6, 4, 5)
变成
(6, 3, 4, 5)
现在6
是在之前3
,是原来的a.shape[0]
。后滚3
是a.shape[1]
。但这是一个不同的roll
规范。
它start
取决于如何定义。是原始顺序中的位置,还是返回顺序中的位置?
如果你喜欢认为start
作为最终形状的索引位置,岂不是很简单的删除before
部分,只是说“移动axis
到dest
空位”?
myroll(a, axis=3, dest=0) => (np.transpose(a,[3,0,1,2])
myroll(a, axis=1, dest=3) => (np.transpose(a,[0,2,3,1])
简单地放弃-=1
测试就可以解决问题(省略负数和边界的处理)
def myroll(a,axis,dest):
x=list(range(a.ndim))
x.remove(axis)
x.insert(dest,axis)
return a.transpose(x)