Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何使用';在';和';不在';就像在SQL中一样_Python_Pandas_Dataframe_Sql Function - Fatal编程技术网

Python 如何使用';在';和';不在';就像在SQL中一样

Python 如何使用';在';和';不在';就像在SQL中一样,python,pandas,dataframe,sql-function,Python,Pandas,Dataframe,Sql Function,如何实现SQL在中的和在中的的等价物 我有一个包含所需值的列表。 以下是场景: 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', 'U

如何实现SQL在中的
和在
中的
的等价物

我有一个包含所需值的列表。 以下是场景:

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'])]
但这似乎是一个可怕的混乱。有人可以改进吗?

您可以使用

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

或者对于“不在”:
~something.isin(某处)

例如:

import pandas as pd

>>> 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

我通常对这样的行进行常规筛选:

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

我想筛选出具有业务ID的dfbc行,该业务ID也在dfProfilesBusIds的业务ID中

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

使用以下方法的替代解决方案:

在中实施

df[df.countries.isin(countries)]
不在其他国家/地区实施

df[df.countries.isin([x for x in np.unique(df.countries) if x not in countries])]
如何为数据帧实现“in”和“not in”? Pandas提供了两种方法:和分别用于系列和数据帧


基于一列筛选数据帧(也适用于系列) 最常见的场景是对特定列应用
isin
条件来过滤数据帧中的行

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


过滤多个列 有时,您需要对多列中的某些搜索词应用“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的行
,我们可以沿第一个轴使用
任意

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等效项:

为什么值得考虑?由于开销较低,NumPy函数通常比它们的等价函数快一点。由于这是一个不依赖于索引对齐的元素操作,因此在极少数情况下,此方法不是pandas的
isin
的合适替代方法

熊猫例程在处理字符串时通常是迭代的,因为字符串操作很难矢量化。 我们现在求助于检查中的

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

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

对于IN:
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(df[“A”].isin([3,6])]


  • 如果要保持列表的顺序,请使用以下技巧:

    df = pd.DataFrame({'country': ['US', 'UK', 'Germany', 'China']})
    countries_to_keep = ['Germany', 'US']
    
    
    ind=[df.index[df['country']==i].tolist() for i in countries_to_keep]
    flat_ind=[item for sublist in ind for item in sublist]
    
    df.reindex(flat_ind)
    
       country
    2  Germany
    0       US
    

    仅供参考,这比@DSM soln慢得多,后者是vectorized@Jeff我希望如此,但当我需要直接过滤掉熊猫中不可用的东西时,我又回到了这一点。(我正要说“像.startwith或regex匹配,但刚刚发现Series.str具备所有这些!)如果你真的在处理一维数组(像在你的例子中),那么在你的第一行使用一个系列而不是一个数据帧,像@DSM used:
    df=pd.Series({'countries':['US','UK'demany','China']))
    @TomAugspurger:像往常一样,我可能遗漏了什么。
    df
    ,我的和他的,都是一个
    数据框架
    国家
    是一个列表。
    df[~df.countries.isin(国家)]
    生成的是一个
    数据帧
    ,而不是一个
    系列
    ,甚至在0.11.0.dev-14a04dd中也能正常工作。这个答案令人困惑,因为您一直在重复使用
    国家
    变量。好吧,OP可以做到这一点,这是继承的,但以前做得不好的事情并不能证明现在做得不好。@ifly6:同意,我疯了当我遇到一个错误时,我意识到了同样的错误:“'DataFrame'对象没有属性'countries',对于那些被波浪线弄糊涂的人(像我一样):你可以否定isin(正如在接受的答案中所做的那样),而不是与FalseRelated(性能/内部结构)相比较:类似,但否定词
    ~
    在2019年作为编辑添加。这主要是重复其他答案中的信息。使用
    logical\u not
    相当于
    ~
    运算符。我喜欢它,但如果我想比较df3中的一列与df1列中的一列,该怎么办?那会是什么样子?查询的可读性好得多。特别是对于“不在”场景,vs远处的瓷砖。谢谢
    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)
    
    df2[df2[['A', 'B']].isin(c1).all(axis=1)]
    
       A  B  C
    0  x  w  0
    
    # `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
    
    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
    
    df = pd.DataFrame({'country': ['US', 'UK', 'Germany', 'China']})
    countries_to_keep = ['Germany', 'US']
    
    
    ind=[df.index[df['country']==i].tolist() for i in countries_to_keep]
    flat_ind=[item for sublist in ind for item in sublist]
    
    df.reindex(flat_ind)
    
       country
    2  Germany
    0       US