팬더 시리즈를 필터링하는 방법


94

groupby ( 'name')을 수행하고 다른 열에 mean () 함수를 사용한 후 이와 같은 Series가 있습니다.

name
383      3.000000
663      1.000000
726      1.000000
737      9.000000
833      8.166667

누구든지 1.000000 평균 값으로 행을 필터링하는 방법을 보여 주시겠습니까? 감사합니다. 도움을 주셔서 대단히 감사합니다.


글쎄, 주어진 조건에 따라 시리즈를 어떻게 필터링할까요?

답변:


127
In [5]:

import pandas as pd

test = {
383:    3.000000,
663:    1.000000,
726:    1.000000,
737:    9.000000,
833:    8.166667
}

s = pd.Series(test)
s = s[s != 1]
s
Out[0]:
383    3.000000
737    9.000000
833    8.166667
dtype: float64

10
아래 답변은 연결될 수 있기 때문에 선호합니다 (즉 s표현식에서 정의한 다음 두 번 사용할 필요가 없음 ). 하지만 판다 0.18에서만 작동합니다.
IanS

piRSquared의 답변 에서 타이밍 비교도 참조하십시오 .
IanS

63

팬더 버전 0.18+ 필터링에서 시리즈를 아래와 같이 수행 할 수도 있습니다.

test = {
383:    3.000000,
663:    1.000000,
726:    1.000000,
737:    9.000000,
833:    8.166667
}

pd.Series(test).where(lambda x : x!=1).dropna()

체크 아웃 : http://pandas.pydata.org/pandas-docs/version/0.18.1/whatsnew.html#method-chaininng-improvements


3
메소드 체인과 함께 그래서 훨씬 좋네요 (그리고 불꽃을 생각 나게한다.)
딜런 호그

사실이지만 Spark는이 경우에 더 직관적 인 작업을 수행합니다. 단순히 술어와 일치하지 않는 행을 제거합니다. 즉, 문서를 읽을 때까지 분명하게 불필요 해 보이는 ".dropna ()"부분을 사용하지 않음을 의미합니다. 그것에 의해 물렸다 : D
Florent Moiny

44

으로 DACW 지적 , 거기 메소드 체인 개선 당신은 매우 친절 찾고있는 무엇 팬더 0.18.1에가.

를 사용하는 대신 인덱서 또는 Series 인덱서에 .where함수를 전달 하고 다음 호출을 피할 수 있습니다 ..loc[].dropna

test = pd.Series({
383:    3.000000,
663:    1.000000,
726:    1.000000,
737:    9.000000,
833:    8.166667
})

test.loc[lambda x : x!=1]

test[lambda x: x!=1]

유사한 동작이 DataFrame 및 NDFrame 클래스에서 지원됩니다.


2
이것은 내가 가장 좋아하는 대답이며 numpy로 내려 가지 않고 가장 빠른 것 같습니다 (타이밍 비교 참조).
IanS

21

이를 수행하는 빠른 방법은 numpy기본 배열을 슬라이스하는 데 사용하여 재구성하는 것입니다. 아래 타이밍을 참조하십시오.

mask = s.values != 1
pd.Series(s.values[mask], s.index[mask])

0
383    3.000000
737    9.000000
833    8.166667
dtype: float64

순진한 타이밍

여기에 이미지 설명 입력


, 나는 당신의 방법을 좋아합니다, 내가 멀티 마스크가 있다면 무엇을 알고 싶습니다. Thx
Menglong Li

1
@MenglongLi에 따라 다르므로 질문해야합니다. 대부분의 경우 &와 결합 할 것입니다. 마스크 = MASK1 및 mask2
piRSquared

6

또 다른 방법은 먼저 DataFrame으로 변환하고 쿼리 메서드를 사용하는 것입니다 (numexpr이 설치되어 있다고 가정).

import pandas as pd

test = {
383:    3.000000,
663:    1.000000,
726:    1.000000,
737:    9.000000,
833:    8.166667
}

s = pd.Series(test)
s.to_frame(name='x').query("x != 1")

나는 그것이 문자열로 조건을 통과하는 것이 좋습니다 생각하지 않습니다
SzymonPajzert

1
이것은 데이터 프레임의 모든 오버 헤드를 추가하고 매우 느려질 것입니다.
fantabolous

5

연결 작업이 마음에 들면 compress함수 를 사용할 수도 있습니다 .

test = pd.Series({
383:    3.000000,
663:    1.000000,
726:    1.000000,
737:    9.000000,
833:    8.166667
})

test.compress(lambda x: x != 1)

# 383    3.000000
# 737    9.000000
# 833    8.166667
# dtype: float64

1

제 경우 에는 값이 문자의 튜플 인 팬더 시리즈가 있습니다 .

Out[67]
0    (H, H, H, H)
1    (H, H, H, T)
2    (H, H, T, H)
3    (H, H, T, T)
4    (H, T, H, H)

따라서 인덱싱을 사용하여 시리즈를 필터링 할 수 있지만 인덱스를 생성하려면 apply. 내 조건은 "정확히 하나의 'H'를 가진 모든 튜플 찾기"입니다.

series_of_tuples[series_of_tuples.apply(lambda x: x.count('H')==1)]

나는 그것이 "chainable"아니라는 것을 인정합니다 . (즉, series_of_tuples두 번 반복 합니다. 임시 시리즈를 변수에 저장해야 apply (...)를 호출 할 수 있습니다).

부울 인덱스를 생성하기 위해 요소별로 작동 할 수 있는 다른 메서드 (외에 .apply(...)) 도있을 수 있습니다 .

다음과 같은 연결 가능한 함수를 사용하는 다른 많은 답변 (수락 된 답변 포함) :

  • .compress()
  • .where()
  • .loc[]
  • []

이들은 시리즈 의 개별 값이 아닌 Series에 적용되는 콜 러블 (람다) 허용합니다 !

따라서 위의 조건 / 호출 가능 / 람다를 다음과 같은 체인 가능한 함수와 함께 사용하려고 할 때 내 튜플 시리즈가 이상하게 작동했습니다 .loc[].

series_of_tuples.loc[lambda x: x.count('H')==1]

오류를 생성합니다.

KeyError : '레벨 H는 이름과 동일해야합니다 (없음).'

나는 매우 혼란 스러웠지만series_of_tuples.count(...) 내가 원하는 것이 아닌 Series.count 함수를 사용하는 것 같습니다 .

대체 데이터 구조가 더 좋을 수 있음을 인정합니다.

  • 카테고리 데이터 유형?
  • Dataframe (튜플의 각 요소가 열이 됨)
  • 일련의 문자열 (튜플을 함께 연결) :

이것은 일련의 문자열을 생성합니다.

series_of_tuples.apply(''.join)

그래서 체인 블 을 사용할 수 있습니다.Series.str.count

series_of_tuples.apply(''.join).str.count('H')==1
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.