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,因此+=nrollaxis(a,-2,-3)相同。例如np.rollaxis(a,2,1)。lista.shape[-3]==a.shape[1]也允许负插入位置,但insert不使用该功能。
因此,关键是理解rollaxis对动作,以及理解remove/insert
我怀疑transpose(x)应该是更直观的版本。它是否做到了这一点是另一个问题。
您建议省略rollaxis或全面应用
省略它不会改变你的两个例子。它只影响transpose情况,当start-=1rollaxis(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部分并只说“移动startstart槽”不是更简单吗?
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)

08-24 22:50