SQL IN
과 동등한 것을 어떻게 달성 할 수 NOT 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처럼 보인다. 누구든지 그것을 향상시킬 수 있습니까?
답변
사용할 수 있습니다 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
답변
.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
답변
팬더 DataFrame에 대해 ‘in’과 ‘not in’을 구현하는 방법은 무엇입니까?
팬더 이벤트 두 가지 방법 : Series.isin
및 DataFrame.isin
각각 시리즈 및 DataFrames에 대해.
하나의 열을 기준으로 데이터 프레임 필터링 (시리즈에도 적용)
가장 일반적인 시나리오는 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']
isin
“A”및 “B”열 모두에 조건 을 적용하려면 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
목록 이해 (문자열 데이터)
위에서 설명한 방법 외에도 numpy equivalent :을 사용할 수도 있습니다 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!
답변
나는 일반적으로 다음과 같은 행에 대해 일반 필터링을 수행했습니다.
criterion = lambda row: row['countries'] not in countries
not_in = df[df.apply(criterion, axis=1)]
답변
BUSINESS_ID가 dfProfilesBusIds 인 BUSINESS_ID가있는 dfbc 행을 필터링하고 싶었습니다.
dfbc = dfbc[~dfbc['BUSINESS_ID'].isin(dfProfilesBusIds['BUSINESS_ID'])]
답변
답변에서 가능한 솔루션을 정리합니다.
IN의 경우 : df[df['A'].isin([3, 6])]
NOT IN의 경우 :
-
df[-df["A"].isin([3, 6])]
-
df[~df["A"].isin([3, 6])]
-
df[df["A"].isin([3, 6]) == False]
-
df[np.logical_not(df["A"].isin([3, 6]))]
답변
df = pd.DataFrame({'countries':['US','UK','Germany','China']})
countries = ['UK','China']
구현 :
df[df.countries.isin(countries)]
나머지 국가 에서 와 같이 구현하지 마십시오 .
df[df.countries.isin([x for x in np.unique(df.countries) if x not in countries])]