繁体   English   中英

交换Numpy数组的切片

[英]Swap slices of Numpy arrays

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

我也想使用此功能在数组之间交换值,不仅一次交换一个值,而且交换多个值(不使用temp变量)。 这不是我期望的(我希望第三个维度上的两个条目都可以互换):

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]

有人有主意吗? 当然,我总是可以引入一个附加变量,但是我想知道是否有一种更优雅的方法。

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

我发现这是最简单的:

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

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

(但是请注意有关“最慢运行”的注意事项...如果您尝试用%“-n 1 -r 1”调用%timeit,则会看到更可比的结果-尽管我的解决方案仍然慢了50%-仍在演示是的,缓存会影响时间)

这将起作用。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM