为什么numpy rollaxis如此令人困惑?

时间:2015-04-27 09:16:03

标签: python numpy scipy

numpy rollaxis函数的行为让我感到困惑。 documentation说:

  

向后滚动指定的轴,直到它位于给定位置。

对于UIView参数:

  

滚动轴直到它位于此位置之前。

对我来说,这已经不知何故了。

好的,直接的例子(来自文档):

start

索引1(4)处的轴向后滚动,直到它位于索引4之前。

现在,当>>> a = np.ones((3,4,5,6)) >>> np.rollaxis(a, 1, 4).shape (3, 5, 6, 4) 索引小于start索引时,我们会出现这种情况:

axis

不是在索引1之前将轴移动到索引3,而是以1结束。

为什么?为什么轴不总是滚动到给定的>>> np.rollaxis(a, 3, 1).shape (3, 6, 4, 5) 索引?

3 个答案:

答案 0 :(得分:11)

NumPy v1.11和更新版本包含一个新功能moveaxis,我推荐使用而不是/** * Update the order meta with field value */ add_action( 'woocommerce_checkout_update_order_meta', 'my_custom_checkout_field_update_order_meta' ); function my_custom_checkout_field_update_order_meta( $order_id ) { if ( ! empty( $_POST['cod_custom_field'] ) ) { update_post_meta( $order_id, 'COD Custom Field', sanitize_text_field( $_POST['cod_custom_field'] ) ); } } /** * Display field value on the order edit page */ add_action( 'woocommerce_admin_order_data_after_billing_address', 'my_custom_checkout_field_display_admin_order_meta', 10, 1 ); function my_custom_checkout_field_display_admin_order_meta($order){ echo '<p><strong>'.__('COD Custom Field').':</strong> ' . get_post_meta( $order->id, 'COD Custom Field', true ) . '</p>'; } (免责声明:我写了它!)。源轴总是在目的地结束,没有任何有趣的逐个问题,具体取决于是大于还是小于rollaxis

start

结果:

end

答案 1 :(得分:8)

我们的人类直觉导致了很多混乱 - 我们如何考虑移动轴。我们可以指定多个滚动步骤(前后两步),或最终形状元组中的位置,或相对于原始形状的位置。

我认为理解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]。列表insert也允许使用否定插入位置,但rollaxis不会使用该功能。

因此,关键是理解remove/insert对行动,并理解transpose(x)

我怀疑rollaxis旨在成为transpose的更直观的版本。是否达到这个目标是另一个问题。

您建议省略start-=1或全面申请

省略它不会改变你的2个例子。它仅影响rollaxis(a,1,4)个案,axes.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}}插槽'?

-=1

简单地删除def myroll(a,axis,dest): x=list(range(a.ndim)) x.remove(axis) x.insert(dest,axis) return a.transpose(x) 测试可能会解决问题(省略负数和边界的处理)

<p:dataList value="#{formBean.parentCharactersListEdit}" 
            var="chara" id="testList" itemType="none">
     <f:facet name="header">test </f:facet>
     <div>
        <p:commandButton immediate="true" process="@this" 
           icon="fa fa-group" actionListener="#{formBean.test}"/>
     </div>
</p:dataList>

答案 2 :(得分:1)

a = np.arange(1*2*3*4*5).reshape(1,2,3,4,5)

np.rollaxis(a,axis,start)

'axis'是从0开始移动的轴的索引。在我的例子中,位置0的轴是1.

'start'是我们想要移动所选轴的轴的索引(从0开始)。

因此,如果start = 2,则位置2的轴为3,因此所选轴将位于3之前。

示例:

>>> np.rollaxis(a,0,2).shape # the 1 will be before the 3.

(2, 1, 3, 4, 5)

>>> np.rollaxis(a,0,3).shape # the 1 will be before the 4.

(2, 3, 1, 4, 5)

>>> np.rollaxis(a,1,2).shape # the 2 will be before the 3.

(1, 2, 3, 4, 5)

>>> np.rollaxis(a,1,3).shape # the 2 will be before the 4.

(1, 3, 2, 4, 5)

因此,在滚动之后,滚动之前的轴上的数字将放在滚动前的开始数字之前。

如果你想到这样的rollaxis它很简单并且非常有意义,尽管他们选择以这种方式设计它是很奇怪的。

那么,当轴和开始相同时会发生什么?好吧,你显然不能在它自己之前放一个数字,所以数字不会移动,指令变成无操作。

示例:

>>> np.rollaxis(a,1,1).shape # the 2 can't be moved to before the 2.

(1, 2, 3, 4, 5)

>>> np.rollaxis(a,2, 2).shape # the 3 can't be moved to before the 3.

(1, 2, 3, 4, 5)

如何将轴移动到最后?好吧,结束后没有数字,但你可以在结束后指定start。

示例:

>>> np.rollaxis(a,1,5).shape # the 2 will be moved to the end.

(1, 3, 4, 5, 2)

>>> np.rollaxis(a,2,5).shape # the 3 will be moved to the end.

(1, 2, 4, 5, 3)


>>> np.rollaxis(a,4,5).shape # the 5 is already at the end.

(1, 2, 3, 4, 5)