如何就地反转 NumPy 数组?

Posted

技术标签:

【中文标题】如何就地反转 NumPy 数组?【英文标题】:How to reverse a NumPy array in-place? 【发布时间】:2017-08-26 08:26:22 【问题描述】:

是否有任何有效的方法可以就地逆转 NumPy?

注意:我不是在寻找相反的视图。我希望数组真正反转。

【问题讨论】:

我的猜测是,将反向视图复制回自身是您能做的最好的事情:arr[:]=arr[::-1]。换句话说,数据缓冲区必须被重写。即使这样,您也可能会遇到缓冲问题。 arr[:]=arr[::-1].copy() 可能更安全。 @hpaulj:这也是我的猜测...... 为什么反向视图对您不利? @Julien: a = numpy.asarray([1, 2, 3]); print(numpy.add(a[::-1], 1, a)) @Mehrdad: As of NumPy 1.13,numpy.add(a[::-1], 1, a) 中的别名应该不再是问题。 (我相信这是通过创建副本来实现的。) 【参考方案1】:

这很不优雅,但是如果就地是最重要的因素并且运行时间不那么重要(因为 numpy 切片将远远胜过迭代方法),您总是可以从数组的左端和右端交换索引直到指数收敛:

def reverse(arr):
    ln = arr.shape[0]
    lidx, ridx = 0, ln - 1

    while lidx < ridx:
        rtmp = arr[ridx]
        arr[ridx] = arr[lidx]
        arr[lidx] = rtmp
        lidx += 1
        ridx -= 1

    return arr

这适用于奇数和偶数长度的数组。甚至:

>>> reverse(np.arange(4))
array([3, 2, 1, 0])

奇数:

>>> reverse(np.arange(5))
array([4, 3, 2, 1, 0])

并证明它是就地的:

>>> y = np.arange(6)
>>> x = reverse(y)
>>> x is y
True

【讨论】:

【参考方案2】:

正如 cmets 中所述,这似乎可行。

A = np.array([2,1,3])
B = A.copy()
B = B[...,::-1] 

【讨论】:

这不会将数组反转到位,这正是 OP 所要求的。它所做的只是复制到一个新数组,制作该数组的反向视图,然后用反向视图替换副本。 感谢您的提醒。我的帖子应该带有学生司机警告。您能详细说明两者之间的实际区别吗?即在什么情况下你想要一个而不是另一个? 通常制作新副本并重新绑定名称就可以了。但有时您引用了一个别名对象(在接收参数时最常见;绑定到参数名称的局部变量通常也绑定到调用者范围内的名称)。在这些情况下,重新分配不会影响调用者;通常你想要那个(没有意想不到的副作用),有时你不想要。在这种情况下,OP 非常明确地想要就地操作,因此很明显,在原地重写原始对象很重要。

以上是关于如何就地反转 NumPy 数组?的主要内容,如果未能解决你的问题,请参考以下文章

就地映射 NumPy 数组

如何使用循环反转numpy数组

将numpy数组设置为切片而不进行任何就地操作

如何在numpy中反转排列数组

再次对 Numpy 数组进行就地类型转换?

如何修改 Spark 数据框中的 numpy 数组?