Python:从布尔数组中获取最后n个Trues

时间:2018-05-03 07:05:22

标签: python numpy

我有一个布尔数组,想要将其转换为数组,其中只有last_n_trues True值仍为True。一个简单的例子:

>>> boolean_array = [False, False, True, True, True, False, False]
>>> last_n_trues = 2
>>> desired_output = [False, False, False, True, True, False, False]

我的方法:

>>> import numpy as np
>>> idxs_of_trues = np.where(boolean_array)[0] 
array([2, 3, 4], dtype=int64)

>>> idxs_of_trues_last_n = idxs_of_trues[-last_n_trues:] 
array([3, 4], dtype=int64)

>>> [x in idxs_of_trues_last_n for x in range(0, len(boolean_array))]
[False, False, False, True, True, False, False]

是否有更快的方式?特别是列表理解对我来说似乎很复杂......

3 个答案:

答案 0 :(得分:4)

您应该只需使用np.where

即可
In [116]: x
Out[116]: array([False, False,  True,  True,  True, False, False], dtype=bool)

In [117]: x[np.where(x)[0][:-2]] = False

In [118]: x
Out[118]: array([False, False, False,  True,  True, False, False], dtype=bool)

这只是替换了True

中最后2个不是False的所有x

这仅在np.array$question = "What is your Name"; $query = "SELECT * FROM `def_questions` where `question` LIKE '%$question%' "; 时才有效,因此请在尝试之前验证。

答案 1 :(得分:2)

方法#1:这里有一个cumsum -

def keep_lastNTrue_cumsum(a, n):
    c = np.count_nonzero(a) # or a.sum()
    a[c - a.cumsum() >= n] = 0
    return a

方法#2:另外两个argpartition -

def keep_lastNTrue_argpartition1(a, n):
    c = np.count_nonzero(a) # or a.sum()
    a[np.sort(np.argpartition(a,-n)[-c:])[:-n]] = 0
    return a

def keep_lastNTrue_argpartition2(a, n):
    c = np.count_nonzero(a) # or a.sum()
    p = np.argpartition(a,-n)[-a.sum():]
    cn = c-n
    idx = np.argpartition(p,cn)
    a[p[idx[:cn]]] = 0
    return a

方法#3:另一种掩盖用法更多 -

def keep_lastNTrue_allmask(a, n):
    c = a.sum()
    set_mask = np.ones(c, dtype=bool)
    set_mask[:-n] = False
    a[a] = set_mask
    return a

样品运行 -

In [141]: boolean_array = np.array([False, False, True, True, True, False, False])

In [142]: keep_lastNTrue_cumsum(boolean_array, n=2)
Out[142]: array([False, False, False,  True,  True, False, False])

In [143]: boolean_array = np.array([False, False, True, True, True, False, False])

In [144]: keep_lastNTrue_argpartition1(boolean_array, n=2)
Out[144]: array([False, False, False,  True,  True, False, False])

In [145]: boolean_array = np.array([False, False, True, True, True, False, False])

In [146]: keep_lastNTrue_argpartition2(boolean_array, n=2)
Out[146]: array([False, False, False,  True,  True, False, False])

答案 2 :(得分:1)

没有库的最快方法是克隆列表并反向迭代:

def foo(bools, last_n_trues):
    result = bools[:]
    count = 0
    for i in range(len(bools) - 1, -1, -1):
        if count < last_n_trues:
            if result[i]:
                count += 1
        else:       
            result[i] = False
    return result