Python : 인덱스 세트를 기반으로 목록에서 하위 집합 선택


99

모두 동일한 수의 항목이있는 여러 목록이 있습니다 (각각 개체 속성 지정).

property_a = [545., 656., 5.4, 33.]
property_b = [ 1.2,  1.3, 2.3, 0.3]
...

동일한 길이의 플래그가있는 목록

good_objects = [True, False, False, True]

(동등한 색인 목록으로 쉽게 대체 할 수 있습니다.

good_indices = [0, 3]

항목 또는 색인으로 표시된 값만 포함 하는 새 목록 property_asel, property_bsel... 을 생성하는 가장 쉬운 방법은 무엇입니까 True?

property_asel = [545., 33.]
property_bsel = [ 1.2, 0.3]

답변:


128

목록 이해력을 사용할 수 있습니다 .

property_asel = [val for is_good, val in zip(good_objects, property_a) if is_good]

또는

property_asel = [property_a[i] for i in good_indices]

후자는 즉석에서 생성되는 대신 미리 계산된다는 가정하에 good_indices의 길이보다 작기 때문에 더 빠릅니다 .property_agood_indices


편집 : 첫 번째 옵션은 itertools.compressPython 2.7 / 3.1부터 사용 가능한 것과 동일합니다 . @Gary Kerr 의 답변을 참조하십시오 .

property_asel = list(itertools.compress(property_a, good_objects))

1
@fuen : 네. 파이썬 3에서는 그다지 많은 것이 아니라 파이썬 2에서 많이 발생합니다 ( 대신 itertools.izip 사용). 이것은 zip파이썬 2에서는 새 목록을 만들 것이지만 파이썬 3에서는 (게으른) 생성기를 반환하기 때문입니다.
kennytm 2010

좋습니다. 그러면 두 번째 제안을 고수해야합니다. 이것이 제 코드의 중심 부분을 구성하기 때문입니다.
fuenfundachtzig 2010

4
@ 85 : 왜 성능에 대해 걱정하십니까? 해야 할 일을 작성하고 속도가 느리면 테스트하여 병목 현상을 찾습니다.
Gary Kerr

1
@PreludeAndFugue : 두 가지 동등한 옵션이있는 경우 어느 것이 더 빠른지 알고 즉시 사용하는 것이 좋습니다.
fuenfundachtzig 2010

1
첫 번째 예제 from itertools import izip대신 사용 하고 사용할 수 있습니다 zip. 그러면 Python 3과 같은 반복기가 생성됩니다
.

28

두 가지 옵션이 있습니다.

  1. numpy 사용 :

    property_a = numpy.array([545., 656., 5.4, 33.])
    property_b = numpy.array([ 1.2,  1.3, 2.3, 0.3])
    good_objects = [True, False, False, True]
    good_indices = [0, 3]
    property_asel = property_a[good_objects]
    property_bsel = property_b[good_indices]
    
  2. 목록 이해력을 사용하여 압축합니다.

    property_a = [545., 656., 5.4, 33.]
    property_b = [ 1.2,  1.3, 2.3, 0.3]
    good_objects = [True, False, False, True]
    good_indices = [0, 3]
    property_asel = [x for x, y in zip(property_a, good_objects) if y]
    property_bsel = [property_b[i] for i in good_indices]
    

2
Numpy를 사용하는 것은 OP가 목록에 숫자를 저장하려는 것처럼 보이기 때문에 좋은 제안입니다. 2 차원 배열이 더 좋을 것입니다.
Philipp

이것은 R 사용자에게 매우 친숙한 구문이 될 것이기 때문에 좋은 제안입니다. 이러한 종류의 선택은 특히 중첩 및 / 또는 다차원의 경우 매우 강력합니다.
Thomas Browne 2014 년

[property_b[i] for i in good_indices]없이 사용하기에 좋은 것입니다numpy
Ilya Rusin 2016-08-08

15

내장 함수 zip 사용

property_asel = [a for (a, truth) in zip(property_a, good_objects) if truth]

편집하다

2.7의 새로운 기능을 살펴 보겠습니다. 이제 위의 코드와 유사한 itertools 모듈에 함수가 있습니다.

http://docs.python.org/library/itertools.html#itertools.compress

itertools.compress('ABCDEF', [1,0,1,0,1,1]) =>
  A, C, E, F

1
나는 itertools.compress여기 의 사용에 압도적 입니다. 목록 이해력은 지옥 압축이 수행하는 작업을 파헤칠 필요없이 훨씬 더 읽기 쉽습니다.
PaulMcG 2010

5
흠, 압축을 사용하는 코드는 훨씬 더 읽기 쉽습니다. :) 내가 원하는 것을 정확히 수행하기 때문에 편향된 것일 수 있습니다.
fuenfundachtzig 2010

itertools.compress문서 예제를 복사하여 붙여 넣는 대신 예제를 제공하지 않는 이유는 무엇 입니까?
Nicolas Gervais

8

항목 목록과 참 / 필수 인덱스 목록 만 있다고 가정하면 이것이 가장 빠릅니다.

property_asel = [ property_a[index] for index in good_indices ]

즉, 속성 선택은 참 / 필수 인덱스가있는만큼만 라운드를 수행합니다. 단일 태그 (true / false) 목록의 규칙을 따르는 속성 목록이 많은 경우 동일한 목록 이해 원칙을 사용하여 인덱스 목록을 만들 수 있습니다.

good_indices = [ index for index, item in enumerate(good_objects) if item ]

이는 good_objects의 각 항목을 반복하고 (열거 형으로 해당 인덱스를 기억하면서) 항목이 참인 인덱스 만 반환합니다.


목록을 이해하지 못하는 사람을 위해 굵게 강조 표시된 코드가있는 영어 산문 버전이 있습니다.

대상 목록 에 대한 인덱스 의 모든 그룹 인덱스 항목의 존재 열거좋은 객체 , 경우에 (어디)이 항목이 True를


-1

Matlab 및 Scilab 언어는 귀하가 묻는 질문에 대해 Python보다 더 간단하고 우아한 구문을 제공하므로 Python에서 Numpy 패키지를 사용하여 Matlab / Scilab을 모방하는 것이 최선이라고 생각합니다. 이렇게하면 문제에 대한 해결책이 매우 간결하고 우아합니다.

from numpy import *
property_a = array([545., 656., 5.4, 33.])
property_b = array([ 1.2,  1.3, 2.3, 0.3])
good_objects = [True, False, False, True]
good_indices = [0, 3]
property_asel = property_a[good_objects]
property_bsel = property_b[good_indices]

Numpy는 Matlab / Scilab을 모방하려고 시도하지만 비용이 발생합니다. 모든 목록을 "array"키워드로 선언해야합니다. 이는 스크립트에 과부하를 줄 것입니다 (이 문제는 Matlab / Scilab에는 존재하지 않습니다). 이 솔루션은 귀하의 예제에 해당하는 숫자 배열로 제한됩니다.


5
질문에서 그는 NumPy를 언급하지 않습니다 .NumPy 대 Matlab에 대한 의견을 표현할 필요가 없습니다. 파이썬 목록은 NumPy 배열과 같지 않습니다 . 비록 둘 다 대략 벡터에 해당하더라도. (Python 목록은 Matlab 셀형 배열과 비슷합니다. 각 요소는 다른 데이터 유형을 가질 수 있습니다. NumPy 배열은 특정 최적화를 활성화하기 위해 더 제한됩니다). Python의 내장 filter또는 외부 라이브러리 를 통해 예제와 유사한 구문을 얻을 수 있습니다 pandas. 언어를 바꾸려는 경우 R을 사용해 볼 수도 있지만 질문이 요구하는 것은 아닙니다 .
Livius
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.