我如何才能实现SQL的IN和NOT IN的等价?

我有一个所需值的列表。 场景如下:

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

# pseudo-code:
df[df['country'] not in countries_to_keep]

我目前的做法如下:

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

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

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

但这似乎是一个可怕的拼凑。有人能改进吗?


当前回答

使用.query()方法的替代解决方案:

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

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

其他回答

你也可以在.query()中使用.isin():

df.query('country.isin(@countries_to_keep).values')

# Or alternatively:
df.query('country.isin(["UK", "China"]).values')

要否定你的查询,使用~:

df.query('~country.isin(@countries_to_keep).values')

更新:

另一种方法是使用比较操作符:

df.query('country == @countries_to_keep')

# Or alternatively:
df.query('country == ["UK", "China"]')

要对查询求反,使用!=:

df.query('country != @countries_to_keep')

从答案中整理出可能的解决方案:

用于:df[df['A']。isin ([3], 6)]

对于不在:

df [-df[“A”]。isin ([3], 6)] df [~ df[“A”]。isin ([3], 6)] df [df[“A”]。isin([3,6]) == False] df [np。logical_not“A”(df[]。isin ([3], 6))]

我的2c价值: 我需要一个数据框架的in和ifelse语句的组合,这对我来说很有用。

sale_method = pd.DataFrame(model_data["Sale Method"].str.upper())
sale_method["sale_classification"] = np.where(
    sale_method["Sale Method"].isin(["PRIVATE"]),
    "private",
    np.where(
        sale_method["Sale Method"].str.contains("AUCTION"), "auction", "other"
    ),
)

我通常对行进行泛型过滤,像这样:

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

你可以使用pd.Series.isin。

对于“IN”的用法:something.isin(某处)

或者对于"NOT IN": ~something.isin(某处)

举个例子:

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