在单个操作中使用二进制列表拆分numpy数组

时间:2019-07-08 08:16:55

标签: python numpy split binary

我可以将一个数组分成两个较小的数组,如下所示:

>>> 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])

但是,即使我在同一行上生成selectednot_selected,我还是(至少我认为是)有效地在{{1} }两次,一次与a,再一次与它的逆。我如何使用真正单个的且可能更快的numpy操作生成selectorselected?还是这仍然是最好的方法?

1 个答案:

答案 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