繁体   English   中英

为什么对 numpy 数组进行就地修改的性能与被修改的维度顺序有关?

[英]Why is performance of in-place modification to a numpy array related to the order of dimension being modified?

import numpy as np
a = np.random.random((500, 500, 500))
b = np.random.random((500, 500))

%timeit a[250, :, :] = b
%timeit a[:, 250, :] = b
%timeit a[:, :, 250] = b

107 µs ± 2.76 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
52 µs ± 88.1 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
1.59 ms ± 4.45 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

观察:

  1. 上述三个运行的性能不同:修改第 1 和第 3 维(切片第 2 维)是三者中最快的,而修改第 1 和第 2 维(切片第 3 维)是最慢的。
  2. w.r.t 的速度似乎没有单调性。 被切片的维度。

问题是:

  1. numpy 背后的机制是什么?
  2. 考虑到第一个问题的答案,如何通过正确安排尺寸来加速我的代码,因为某些尺寸是批量修改的,其余的只是被切片?

正如一些评论所指出的那样,这完全与参考的位置有关 想想 numpy 在底层要做些什么,在第三种情况下,memory 中的连续左值彼此相距多远。

另请注意,当数组不是 C 连续而是 F 连续时,计时结果如何变化:

a = np.asfortranarray(a)
b = np.asfortranarray(b)

%timeit a[250, :, :] = b
%timeit a[:, 250, :] = b
%timeit a[:, :, 250] = b

892 µs ± 22 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
169 µs ± 66.4 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
158 µs ± 24.2 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

(非常小的旁注:出于同样的原因,有时在对组进行groupby和一堆重复操作之前对DataFrame进行排序是有利的,这有点违反直觉,因为排序本身需要O(nlogn) )。

暂无
暂无

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

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