SQL에서와 같이 'in'과 'not in'을 사용하여 Pandas 데이터 프레임을 필터링하는 방법

python pandas dataframe sql-function


SQL의 INNOT IN 에 해당하는 것을 어떻게 얻을 수 있습니까?

필요한 값이있는 목록이 있습니다. 시나리오는 다음과 같습니다.

df = pd.DataFrame({'countries':['US','UK','Germany','China']})
countries = ['UK','China']

# pseudo-code:
df[df['countries'] not in countries]

이 작업을 수행하는 현재 방법은 다음과 같습니다.

df = pd.DataFrame({'countries':['US','UK','Germany','China']})
countries = pd.DataFrame({'countries':['UK','China'], 'matched':True})

# IN
df.merge(countries,how='inner',on='countries')

# NOT IN
not_in = df.merge(countries,how='left',on='countries')
not_in = not_in[pd.isnull(not_in['matched'])]

그러나 이것은 끔찍한 kludge처럼 보인다. 누구든지 그것을 향상시킬 수 있습니까?





Answer 1 DSM


pd.Series.isin 을 사용할 수 있습니다 .

"IN"사용 : something.isin(somewhere)

또는 "NOT IN"의 경우 : ~something.isin(somewhere)

실례로 :

>>> df
  countries
0        US
1        UK
2   Germany
3     China
>>> countries
['UK', 'China']
>>> df.countries.isin(countries)
0    False
1     True
2    False
3     True
Name: countries, dtype: bool
>>> df[df.countries.isin(countries)]
  countries
1        UK
3     China
>>> df[~df.countries.isin(countries)]
  countries
0        US
2   Germany



Answer 2 MaxU


.query () 메소드 를 사용하는 대체 솔루션 :

In [5]: df.query("countries in @countries")
Out[5]:
  countries
1        UK
3     China

In [6]: df.query("countries not in @countries")
Out[6]:
  countries
0        US
2   Germany



Answer 3 cs95


팬더 DataFrame에 대해 'in'과 'not in'을 구현하는 방법은 무엇입니까?

Pandas는 Series와 DataFrames에 대해 각각 Series.isin DataFrame.isin 두 가지 방법을 제공합니다 .


하나의 열을 기준으로 데이터 프레임 필터링 (시리즈에도 적용)

가장 일반적인 시나리오는 특정 열에 isin 조건을 적용하여 DataFrame에서 행을 필터링하는 것입니다.

df = pd.DataFrame({'countries': ['US', 'UK', 'Germany', np.nan, 'China']})
df
  countries
0        US
1        UK
2   Germany
3     China

c1 = ['UK', 'China']             # list
c2 = {'Germany'}                 # set
c3 = pd.Series(['China', 'US'])  # Series
c4 = np.array(['US', 'UK'])      # array

Series.isin 은 다양한 유형을 입력으로 허용합니다. 다음은 원하는 것을 얻는 유효한 방법입니다.

df['countries'].isin(c1)

0    False
1     True
2    False
3    False
4     True
Name: countries, dtype: bool

# `in` operation
df[df['countries'].isin(c1)]

  countries
1        UK
4     China

# `not in` operation
df[~df['countries'].isin(c1)]

  countries
0        US
2   Germany
3       NaN

# Filter with `set` (tuples work too)
df[df['countries'].isin(c2)]

  countries
2   Germany

# Filter with another Series
df[df['countries'].isin(c3)]

  countries
0        US
4     China

# Filter with array
df[df['countries'].isin(c4)]

  countries
0        US
1        UK

많은 열에서 필터링

경우에 따라 여러 열에 대해 일부 검색어와 함께 'in'멤버십 확인을 적용하려고 할 수 있습니다.

df2 = pd.DataFrame({
    'A': ['x', 'y', 'z', 'q'], 'B': ['w', 'a', np.nan, 'x'], 'C': np.arange(4)})
df2

   A    B  C
0  x    w  0
1  y    a  1
2  z  NaN  2
3  q    x  3

c1 = ['x', 'w', 'p']

열 "A"와 "B"모두에 isin 조건 을 적용하려면 DataFrame.isin 을 사용 하십시오 .

df2[['A', 'B']].isin(c1)

      A      B
0   True   True
1  False  False
2  False  False
3  False   True

이로부터 적어도 하나의 열이 True 행을 유지 하려면 첫 번째 축을 따라 any 사용할 수 있습니다 .

df2[['A', 'B']].isin(c1).any(axis=1)

0     True
1    False
2    False
3     True
dtype: bool

df2[df2[['A', 'B']].isin(c1).any(axis=1)]

   A  B  C
0  x  w  0
3  q  x  3

모든 열을 검색하려면 열 선택 단계를 생략하고 수행하십시오.

df2.isin(c1).any(axis=1)

마찬가지로 모든 열이 True 행을 유지 하려면 이전과 동일한 방식으로 all 사용 하십시오 .

df2[df2[['A', 'B']].isin(c1).all(axis=1)]

   A  B  C
0  x  w  0

주목할만한 언급 : numpy.isin , query , list comprehensions (string data)

위에서 설명한 방법 외에도 numpy와 동등한 numpy.isin 사용할 수도 있습니다 .

# `in` operation
df[np.isin(df['countries'], c1)]

  countries
1        UK
4     China

# `not in` operation
df[np.isin(df['countries'], c1, invert=True)]

  countries
0        US
2   Germany
3       NaN

고려할 가치가있는 이유는 무엇입니까? NumPy 함수는 일반적으로 오버 헤드가 낮아 팬더에 비해 약간 빠릅니다. 이는 인덱스 정렬에 의존하지 않는 요소 별 연산이므로이 방법이 pandas ' isin 의 적절한 대체 방법이 아닌 상황은 거의 없습니다 .

문자열 작업은 벡터화하기 어렵 기 때문에 문자열 작업시 팬더 루틴은 일반적으로 반복됩니다. 목록 이해가 더 빠를 것이라는 많은 증거가 있습니다. . 우리는 리조트 in 지금 확인.

c1_set = set(c1) # Using `in` with `sets` is a constant time operation... 
                 # This doesn't matter for pandas because the implementation differs.
# `in` operation
df[[x in c1_set for x in df['countries']]]

  countries
1        UK
4     China

# `not in` operation
df[[x not in c1_set for x in df['countries']]]

  countries
0        US
2   Germany
3       NaN

그러나 지정하기가 훨씬 더 어려우므로 수행중인 작업을 모르는 경우 사용하지 마십시오.

마지막 으로이 답변 에서 다루는 DataFrame.query 도 있습니다 . numexpr FTW!




Answer 4 Kos


나는 보통 다음과 같은 행에 대해 일반적인 필터링을 수행했습니다.

criterion = lambda row: row['countries'] not in countries
not_in = df[df.apply(criterion, axis=1)]



Answer 5 Sam Henderson


BUSINESS_ID가 dfProfilesBusIds 인 BUSINESS_ID가있는 dfbc 행을 필터링하고 싶었습니다.

dfbc = dfbc[~dfbc['BUSINESS_ID'].isin(dfProfilesBusIds['BUSINESS_ID'])]