交换Numpy数组的切片

use*_*745 26 python swap numpy multidimensional-array

我喜欢python处理变量交换的方式: a, b, = b, a

我想使用这个功能来交换数组之间的值,不仅一次一个,而且还有一些(不使用临时变量).这不符合我的预期(我希望第三维的两个条目都可以互换):

import numpy as np
a = np.random.randint(0, 10, (2, 3,3))
b = np.random.randint(0, 10, (2, 5,5))
# display before
a[:,0, 0]
b[:,0,0]
a[:,0,0], b[:, 0, 0] = b[:, 0, 0], a[:,0,0] #swap
# display after
a[:,0, 0]
b[:,0,0]
Run Code Online (Sandbox Code Playgroud)

有没有人有想法?当然我总是可以引入一个额外的变量,但我想知道是否有更优雅的方式来做到这一点.

use*_*342 22

Python正确地解释了代码,就像使用了其他变量一样,因此交换代码相当于:

t1 = b[:,0,0]
t2 = a[:,0,0]
a[:,0,0] = t1
b[:,0,0] = t2
Run Code Online (Sandbox Code Playgroud)

但是,即使这段代码也没有正确交换值!这是因为Numpy 切片不急于复制数据,而是创建现有数据的视图.仅在分配切片时执行复制,但在交换时,没有中间缓冲区的副本会破坏您的数据.这就是为什么你不仅需要一个额外的变量,而且还需要一个额外的numpy缓冲区,一般的Python语法都不知道.例如,这可以按预期工作:

t = np.copy(a[:,0,0])
a[:,0,0] = b[:,0,0]
b[:,0,0] = t
Run Code Online (Sandbox Code Playgroud)


bla*_*laz 7

我发现这是最简单的:

a[:,0,0], b[:, 0, 0] = b[:, 0, 0], a[:, 0, 0].copy() #swap
Run Code Online (Sandbox Code Playgroud)

时间比较:

%timeit a[:,0,0], b[:, 0, 0] = b[:, 0, 0], a[:, 0, 0].copy() #swap
The slowest run took 10.79 times longer than the fastest. This could mean that an intermediate result is being cached 
1000000 loops, best of 3: 1.75 µs per loop

%timeit t = np.copy(a[:,0,0]); a[:,0,0] = b[:,0,0]; b[:,0,0] = t
The slowest run took 10.88 times longer than the fastest. This could mean that an intermediate result is being cached 
100000 loops, best of 3: 2.68 µs per loop
Run Code Online (Sandbox Code Playgroud)