numpy rollaxis函数的行为让我很困惑。
documentation表示:
向后滚动指定轴,直到其位于给定位置。
对于start
参数:
轴被滚动到该位置之前。
对我来说,这已经是不一致的了。
好的,直截了当的例子(来自文档):
>>> a = np.ones((3,4,5,6))
>>> np.rollaxis(a, 1, 4).shape
(3, 5, 6, 4)
索引1(4)处的轴向后滚动,直到它位于索引4之前。
现在,当
start
索引小于axis
索引时,我们有如下行为:>>> np.rollaxis(a, 3, 1).shape
(3, 6, 4, 5)
它不是在索引1之前移动索引3处的轴,而是在1处结束。
为什么?为什么轴不总是滚动到给定的
start
索引? 最佳答案
很多困惑都源于我们人类的直觉——我们对移动轴的看法。我们可以指定多个滚动步骤(后退或后退两步),或者最终形状元组中的位置,或者相对于原始形状的位置。
我认为理解rollaxis
的关键是关注原始形状的槽。我能想到的最一般的说法是:
滚动到a.shape[axis]
之前的位置
在此上下文中,a.shape[start]
的含义与listbefore
中的含义相同。所以可以在结束前插入。insert()
的基本作用是:
axes = list(range(0, n))
axes.remove(axis)
axes.insert(start, axis)
return a.transpose(axes)
如果
rollaxis
,则axis<start
将解释start-=1
操作。负值得到
remove
,因此+=n
与rollaxis(a,-2,-3)
相同。例如np.rollaxis(a,2,1)
。lista.shape[-3]==a.shape[1]
也允许负插入位置,但insert
不使用该功能。因此,关键是理解
rollaxis
对动作,以及理解remove/insert
。我怀疑
transpose(x)
应该是更直观的版本。它是否做到了这一点是另一个问题。您建议省略
rollaxis
或全面应用省略它不会改变你的两个例子。它只影响
transpose
情况,当start-=1
为rollaxis(a,1,4)
时,axes.insert(4,1)
与axes.insert(3,1)
相同。axes
仍放在末尾。稍微改变一下测试:np.rollaxis(a,1,3).shape
# (3, 5, 4, 6) # a.shape[1](4) placed before a.shape[3](6)
没有
[0,2,3]
# 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)
现在,
-=1
在原来的-=1
之前。在滚动之后,6
就是3
。但这是一个不同的a.shape[0]
规范。归根结底,这取决于
3
是如何定义的。是原始订单中的过账,还是退回订单中的位置?如果您更愿意将
a.shape[1]
看作是最终形状中的索引位置,那么删除roll
部分并只说“移动start
到start
槽”不是更简单吗?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])
只需去掉
before
测试就可以做到这一点(省略对负数和边界的处理)。def myroll(a,axis,dest):
x=list(range(a.ndim))
x.remove(axis)
x.insert(dest,axis)
return a.transpose(x)