如何就地反转 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 数组?的主要内容,如果未能解决你的问题,请参考以下文章