programing

부울 목록을 기준으로 목록 필터링

subpage 2023. 4. 14. 21:42
반응형

부울 목록을 기준으로 목록 필터링

부울 목록 내의 값이 지정된 경우 필터링해야 하는 값 목록이 있습니다.

list_a = [1, 2, 4, 6]
filter = [True, False, True, False]

다음 행으로 필터링된 새 목록을 생성합니다.

filtered_list = [i for indx,i in enumerate(list_a) if filter[indx] == True]

그 결과, 다음과 같습니다.

print filtered_list
[1,4]

라인은 작동하지만 (내 눈에는) 좀 과해 보여서 같은 일을 할 수 있는 더 간단한 방법이 없을까 생각했다.


어드바이스

아래 답변에서 제시된 두 가지 유용한 조언의 요약:

1-목록 이름 지정 안 함filter내장된 기능이기 때문에 제가 했던 것처럼요.

2 - 비교하지 말 것True에서 했던 것처럼if filter[idx]==True..필요없으니까.사용하고 있는 것만으로if filter[idx]충분합니다.

다음 항목을 찾고 있습니다.

>>> from itertools import compress
>>> list_a = [1, 2, 4, 6]
>>> fil = [True, False, True, False]
>>> list(compress(list_a, fil))
[1, 4]

타이밍 비교(py3.x):

>>> list_a = [1, 2, 4, 6]
>>> fil = [True, False, True, False]
>>> %timeit list(compress(list_a, fil))
100000 loops, best of 3: 2.58 us per loop
>>> %timeit [i for (i, v) in zip(list_a, fil) if v]  #winner
100000 loops, best of 3: 1.98 us per loop

>>> list_a = [1, 2, 4, 6]*100
>>> fil = [True, False, True, False]*100
>>> %timeit list(compress(list_a, fil))              #winner
10000 loops, best of 3: 24.3 us per loop
>>> %timeit [i for (i, v) in zip(list_a, fil) if v]
10000 loops, best of 3: 82 us per loop

>>> list_a = [1, 2, 4, 6]*10000
>>> fil = [True, False, True, False]*10000
>>> %timeit list(compress(list_a, fil))              #winner
1000 loops, best of 3: 1.66 ms per loop
>>> %timeit [i for (i, v) in zip(list_a, fil) if v] 
100 loops, best of 3: 7.65 ms per loop

사용하지 않다filter변수 이름으로서 빌트인 함수입니다.

다음과 같은 경우:

filtered_list = [i for (i, v) in zip(list_a, filter) if v]

사용.zip인덱싱 없이 여러 시퀀스에 걸쳐 병렬로 반복하는 피톤식 방법입니다.이것은, 양쪽 시퀀스의 길이가 같은 것을 전제로 하고 있습니다(최단 기한이 지나면 zip이 정지합니다).사용.itertools그런 간단한 경우는 좀 과잉 살상입니다...

이 예에서 해야 할 한 가지 작업은 작업을 True와 비교하는 것입니다.이는 보통 필요하지 않습니다.대신if filter[idx]==True: ..., 간단하게 쓸 수 있습니다.if filter[idx]: ....

numpy 포함:

In [128]: list_a = np.array([1, 2, 4, 6])
In [129]: filter = np.array([True, False, True, False])
In [130]: list_a[filter]

Out[130]: array([1, 4])

또는 list_a가 numpy 배열일 수 있지만 필터링할 수 없는 경우 Alex Szatmary의 답변을 참조하십시오.

Numpy는 보통 속도도 크게 향상시킵니다.

In [133]: list_a = [1, 2, 4, 6]*10000
In [134]: fil = [True, False, True, False]*10000
In [135]: list_a_np = np.array(list_a)
In [136]: fil_np = np.array(fil)

In [139]: %timeit list(itertools.compress(list_a, fil))
1000 loops, best of 3: 625 us per loop

In [140]: %timeit list_a_np[fil_np]
10000 loops, best of 3: 173 us per loop

numpy를 사용하여 이를 수행하려면 (어레이가 있는 경우)a대신list_a:

a = np.array([1, 2, 4, 6])
my_filter = np.array([True, False, True, False], dtype=bool)
a[my_filter]
> array([1, 4])
filtered_list = [list_a[i] for i in range(len(list_a)) if filter[i]]

그렇게 우아하지는 않지만, 이 솔루션이 더 간단한 구문이라고 생각합니다.이름을 바꿨어요filter로.filter_내장 기능과의 충돌을 피하기 위해:

list_a = [1, 2, 4, 6]
filter_ = [True, False, True, False]

해결책은 다음과 같습니다.

index = [i for i in range(len(filter_)) if filter_[i]]
list_a_filtered = [list_a[i] for i in index]

또는 한 줄:

list_a_filtered = [list_a[i] for i in [j for j in range(len(filter_)) if filter_[j]]]

python 3에서는 사용할 수 있습니다.list_a[filter]갖기 위해True가치.갖기 위해False값 사용list_a[~filter]

언급URL : https://stackoverflow.com/questions/18665873/filtering-a-list-based-on-a-list-of-booleans

반응형