根据来自另一个列表的 True/False 从列表中过滤元素
Filter elements from list based on True/False from another list
在 vanilla Python 3 中是否有一种惯用的方法来屏蔽数组的元素?例如:
a = [True, False, True, False]
b = [2, 3, 5, 7]
b[a]
我希望 b[a]
会 return [2, 5]
,但我得到一个错误:
TypeError: list indices must be integers or slices, not list
在 R 中,这按我预期的方式工作(使用 c()
而不是 []
来创建列表)。我知道 NumPy 有 MaskedArray
可以做到这一点,我正在寻找一种惯用的方法来在普通香草 Python 中做到这一点。当然,我可以使用循环并遍历掩码列表和元素列表,但我希望有一种更有效的方法来使用更高级别的抽象来掩码元素。
我认为没有很多方法可以做到这一点,您可以使用 zip
:
print([y for x, y in zip(a, b) if x])
输出:
[2, 5]
您还可以为此创建一个 class
和 __getitem__
:
class index:
def __init__(self, seq):
self.seq = seq
def __getitem__(self, boolseq):
return [x for x, y in zip(boolseq, self.seq) if y]
print(index(a)[b])
输出:
[2, 5]
您可以使用 itertools.compress
:
>>> from itertools import compress
>>> a = [True, False, True, False]
>>> b = [2, 3, 5, 7]
>>> list(compress(b, a))
[2, 5]
参考"itertools.compress()" document了解更多详情
您可以使用列表理解:
[b[i] for i in range(len(a)) if a[i]]
或
[b[i] for i,mask in enumerate(a) if maks]
在这两种情况下,列表都是通过遍历每个元素创建的,并且仅在掩码为 true
时插入它。
在众多选项中,您可以:
1。使用 itertools compress
from itertools import compress
a = [True, False, True, False]
b = [2, 3, 5, 7]
result_itertools = list(compress(b, a))
print(result_itertools)
2。使用 Filter Function
result_filter = list(filter(lambda x: x[0], zip(a, b)))
for item in result_filter:
print(item[1])
# 2
# 5
3。使用 List Comprehension
result_comprehension = [value for bool_, value in zip(a, b) if bool_]
print(result_comprehension)
# [2, 5]
您可以使用 pandas.Series
,它允许像数据框一样使用布尔数组过滤数据
from pandas import Series
a = [True, False, True, False]
b = [2, 3, 5, 7]
res = Series(b)[a].tolist()
print(res) # [2, 5]
在 vanilla Python 3 中是否有一种惯用的方法来屏蔽数组的元素?例如:
a = [True, False, True, False]
b = [2, 3, 5, 7]
b[a]
我希望 b[a]
会 return [2, 5]
,但我得到一个错误:
TypeError: list indices must be integers or slices, not list
在 R 中,这按我预期的方式工作(使用 c()
而不是 []
来创建列表)。我知道 NumPy 有 MaskedArray
可以做到这一点,我正在寻找一种惯用的方法来在普通香草 Python 中做到这一点。当然,我可以使用循环并遍历掩码列表和元素列表,但我希望有一种更有效的方法来使用更高级别的抽象来掩码元素。
我认为没有很多方法可以做到这一点,您可以使用 zip
:
print([y for x, y in zip(a, b) if x])
输出:
[2, 5]
您还可以为此创建一个 class
和 __getitem__
:
class index:
def __init__(self, seq):
self.seq = seq
def __getitem__(self, boolseq):
return [x for x, y in zip(boolseq, self.seq) if y]
print(index(a)[b])
输出:
[2, 5]
您可以使用 itertools.compress
:
>>> from itertools import compress
>>> a = [True, False, True, False]
>>> b = [2, 3, 5, 7]
>>> list(compress(b, a))
[2, 5]
参考"itertools.compress()" document了解更多详情
您可以使用列表理解:
[b[i] for i in range(len(a)) if a[i]]
或
[b[i] for i,mask in enumerate(a) if maks]
在这两种情况下,列表都是通过遍历每个元素创建的,并且仅在掩码为 true
时插入它。
在众多选项中,您可以:
1。使用 itertools compress
from itertools import compress
a = [True, False, True, False]
b = [2, 3, 5, 7]
result_itertools = list(compress(b, a))
print(result_itertools)
2。使用 Filter Function
result_filter = list(filter(lambda x: x[0], zip(a, b)))
for item in result_filter:
print(item[1])
# 2
# 5
3。使用 List Comprehension
result_comprehension = [value for bool_, value in zip(a, b) if bool_]
print(result_comprehension)
# [2, 5]
您可以使用 pandas.Series
,它允许像数据框一样使用布尔数组过滤数据
from pandas import Series
a = [True, False, True, False]
b = [2, 3, 5, 7]
res = Series(b)[a].tolist()
print(res) # [2, 5]