【发布时间】:2019-07-25 09:57:24
【问题描述】:
我有一个大型 2D numpy 数组。我希望能够在不复制数据的情况下对列的子集高效地运行逐行操作。
接下来,
a = np.arange(1000000).reshape(1000, 10000) 和 columns = np.arange(1, 1000, 2)。供参考,
In [4]: %timeit a.sum(axis=1)
7.26 ms ± 431 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
我知道的方法是:
- 带有列列表的精美索引
In [5]: %timeit a[:, columns].sum(axis=1)
42.5 ms ± 197 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
- 带有列掩码的精美索引
In [6]: cols_mask = np.zeros(10000, dtype=bool)
...: cols_mask[columns] = True
In [7]: %timeit a[:, cols_mask].sum(axis=1)
42.1 ms ± 302 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
- 屏蔽数组
In [8]: cells_mask = np.ones((1000, 10000), dtype=bool)
In [9]: cells_mask[:, columns] = False
In [10]: am = np.ma.masked_array(a, mask=cells_mask)
In [11]: %timeit am.sum(axis=1)
80 ms ± 2.71 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
- python 循环
In [12]: %timeit sum([a[:, i] for i in columns])
31.2 ms ± 531 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
让我有些惊讶的是,最后一种方法是最有效的:此外,它避免了复制完整数据,这对我来说是一个先决条件。但是,它仍然比简单求和慢得多(数据大小翻倍),最重要的是,它可以推广到其他操作(例如,cumsum)。
有什么我缺少的方法吗?我可以编写一些 cython 代码,但我希望该方法适用于任何 numpy 函数,而不仅仅是 sum。
【问题讨论】:
标签: python arrays numpy cython