我可以将一个数组分成两个较小的数组,如下所示:
>>> import numpy as np
>>> a = np.array([1,2,3,4,5])
>>> selector = np.array([True, False, True, True, False])
>>> selected, not_selected = a[selector], a[~ selector]
>>> selected
array([1, 3, 4])
>>> not_selected
array([2, 5])
但是,即使我在同一行上生成selected
和not_selected
,我还是(至少我认为是)有效地在{{1} }两次,一次与a
,再一次与它的逆。我如何使用真正单个的且可能更快的numpy操作生成selector
和selected
?还是这仍然是最好的方法?
答案 0 :(得分:2)
如果您对numba
开放,我们可以提高内存效率,并将其转换为明显的性能。增强-
from numba import njit
@njit(parallel=True)
def select_numba(a, selector, out1, out2):
iter1 = 0
iter2 = 0
for i,j in zip(a,selector):
if j:
out1[iter1] = i
iter1 += 1
else:
out2[iter2] = i
iter2 += 1
return out1,out2
def select(a, selector):
L = np.count_nonzero(selector)
nL = len(selector)-L
out1 = np.empty(L, dtype=a.dtype)
out2 = np.empty(nL, dtype=a.dtype)
select_numba(a,selector, out1, out2)
return out1,out2
样品运行-
In [65]: a = np.array([1,2,3,4,5])
...: selector = np.array([True, False, True, True, False])
In [66]: select(a, selector)
Out[66]: (array([1, 3, 4]), array([2, 5]))
对大型数据集进行基准测试
In [60]: np.random.seed(0)
...: a = np.random.randint(0,9,(100000))
...: selector = np.random.rand(len(a))>0.5
In [62]: %timeit selected, not_selected = a[selector], a[~ selector]
1000 loops, best of 3: 1.2 ms per loop
In [63]: %timeit select(a, selector)
1000 loops, best of 3: 454 µs per loop