numpy的阵列的交换片(Swap slices of Numpy arrays)

2019-07-20 02:32发布

我喜欢蟒蛇的方式处理的变量互换: 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]

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

Answer 1:

Python的正确解释,如果你使用的其他变量的代码,所以交换代码等同于:

t1 = b[:,0,0]
t2 = a[:,0,0]
a[:,0,0] = t1
b[:,0,0] = t2

然而,即使这个代码不正确的交换价值! 这是因为numpy的切片不急于复制数据,他们创建视图到现有的数据。 副本只能在当分片分配给点进行,但是当交换,没有一个中间缓冲区拷贝破坏你的数据。 这就是为什么你需要的不仅是一个额外的变量,但额外的numpy的缓冲区,一般Python语法可以一无所知。 例如,这按预期工作:

t = np.copy(a[:,0,0])
a[:,0,0] = b[:,0,0]
b[:,0,0] = t


Answer 2:

我觉得这是最简单的:

a[:,0,0], b[:, 0, 0] = b[:, 0, 0], a[:, 0, 0].copy() #swap

时间比较:

%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


Answer 3:

user4815162342的答案确实是“正确”的。 但是,如果你一个班轮之后真的,那么考虑一下:

a[arange(2),0,0], b[arange(2), 0, 0] = b[arange(2), 0, 0], a[arange(2),0,0] #swap

但是,这是显著效率较低:

In [12]: %timeit a[arange(2),0,0], b[arange(2), 0, 0] = b[arange(2), 0, 0], a[arange(2),0,0]
10000 loops, best of 3: 32.2 µs per loop

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

(但要注意的说明关于“最慢跑” ......如果你尝试调用%timeit与“-n 1 -r 1”,你会看到更多类似的结果 - 虽然我的解决方案仍然〜50%的速度较慢 - 展示那是,缓存是影响时序)



Answer 4:

这将工作。

a[:,0,0], b[:, 0, 0] = b[:, 0, 0].copy(), a[:, 0, 0].copy()


文章来源: Swap slices of Numpy arrays