从数据框中选择包含特定值的行

2024-04-16 12:12:20 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个pandas数据框,其条目都是字符串:

   A     B      C
1 apple  banana pear
2 pear   pear   apple
3 banana pear   pear
4 apple  apple  pear

等等,我想选择包含某个字符串的所有行,比如“banana”。我不知道每次都会出现在哪一列。当然,我可以编写for循环并遍历所有行。但有没有更简单或更快的方法来做到这一点


Tags: 数据方法字符串applepandasfor条目banana
3条回答

导言

在选择行的核心,我们需要一个1D掩码或一系列长度与df长度相同的布尔元素,我们称之为mask。因此,最后使用df[mask],我们将在boolean-indexing之后的df中获得所选行

这是我们的开始df

In [42]: df
Out[42]: 
        A       B      C
1   apple  banana   pear
2    pear    pear  apple
3  banana    pear   pear
4   apple   apple   pear

I.匹配一个字符串

现在,如果我们只需要匹配一个字符串,它是向前的,元素相等:

In [42]: df == 'banana'
Out[42]: 
       A      B      C
1  False   True  False
2  False  False  False
3   True  False  False
4  False  False  False

如果我们需要在每行中查找ANY一个匹配项,请使用.any方法:

In [43]: (df == 'banana').any(axis=1)
Out[43]: 
1     True
2    False
3     True
4    False
dtype: bool

要选择相应的行,请执行以下操作:

In [44]: df[(df == 'banana').any(axis=1)]
Out[44]: 
        A       B     C
1   apple  banana  pear
3  banana    pear  pear

二,。匹配多个字符串

1。搜索ANY匹配项

这是我们的开始df

In [42]: df
Out[42]: 
        A       B      C
1   apple  banana   pear
2    pear    pear  apple
3  banana    pear   pear
4   apple   apple   pear

NumPy的^{}将在这里工作(或者使用其他帖子中列出的pandas.isin)从^{中的搜索字符串列表中获取所有匹配项。所以,假设我们在{}中寻找{}或{}:

In [51]: np.isin(df, ['pear','apple'])
Out[51]: 
array([[ True, False,  True],
       [ True,  True,  True],
       [False,  True,  True],
       [ True,  True,  True]])

# ANY match along each row
In [52]: np.isin(df, ['pear','apple']).any(axis=1)
Out[52]: array([ True,  True,  True,  True])

# Select corresponding rows with masking
In [56]: df[np.isin(df, ['pear','apple']).any(axis=1)]
Out[56]: 
        A       B      C
1   apple  banana   pear
2    pear    pear  apple
3  banana    pear   pear
4   apple   apple   pear

2。搜索ALL匹配项

这是我们的开始df

In [42]: df
Out[42]: 
        A       B      C
1   apple  banana   pear
2    pear    pear  apple
3  banana    pear   pear
4   apple   apple   pear

因此,现在我们正在寻找具有BOTH的行,比如['pear','apple']。我们将利用NumPy-broadcasting

In [66]: np.equal.outer(df.to_numpy(copy=False),  ['pear','apple']).any(axis=1)
Out[66]: 
array([[ True,  True],
       [ True,  True],
       [ True, False],
       [ True,  True]])

因此,我们有一个2项的搜索列表,因此我们有一个带有number of rows = len(df)number of cols = number of search items的2D掩码。因此,在上面的结果中,第一个col表示'pear',第二个col表示'apple'

为了使事情具体化,让我们为三个项目['apple','banana', 'pear']设置一个掩码:

In [62]: np.equal.outer(df.to_numpy(copy=False),  ['apple','banana', 'pear']).any(axis=1)
Out[62]: 
array([[ True,  True,  True],
       [ True, False,  True],
       [False,  True,  True],
       [ True, False,  True]])

此掩码的列分别用于'apple','banana', 'pear'

回到2搜索项目案例,我们之前有:

In [66]: np.equal.outer(df.to_numpy(copy=False),  ['pear','apple']).any(axis=1)
Out[66]: 
array([[ True,  True],
       [ True,  True],
       [ True, False],
       [ True,  True]])

因为,我们在每行中查找ALL个匹配项:

In [67]: np.equal.outer(df.to_numpy(copy=False),  ['pear','apple']).any(axis=1).all(axis=1)
Out[67]: array([ True,  True, False,  True])

最后,选择行:

In [70]: df[np.equal.outer(df.to_numpy(copy=False),  ['pear','apple']).any(axis=1).all(axis=1)]
Out[70]: 
       A       B      C
1  apple  banana   pear
2   pear    pear  apple
4  apple   apple   pear

您可以通过将整个df与字符串进行比较来创建一个布尔掩码,并调用dropnapassing paramhow='all'删除字符串未出现在所有列中的行:

In [59]:
df[df == 'banana'].dropna(how='all')

Out[59]:
        A       B    C
1     NaN  banana  NaN
3  banana     NaN  NaN

要测试多个值,可以使用多个遮罩:

In [90]:
banana = df[(df=='banana')].dropna(how='all')
banana

Out[90]:
        A       B    C
1     NaN  banana  NaN
3  banana     NaN  NaN

In [91]:    
apple = df[(df=='apple')].dropna(how='all')
apple

Out[91]:
       A      B      C
1  apple    NaN    NaN
2    NaN    NaN  apple
4  apple  apple    NaN

您可以使用index.intersection仅为常用索引值编制索引:

In [93]:
df.loc[apple.index.intersection(banana.index)]

Out[93]:
       A       B     C
1  apple  banana  pear

对于单个搜索值

df[df.values  == "banana"]

 df[df.isin(['banana'])]

对于多个搜索词:

  df[(df.values  == "banana")|(df.values  == "apple" ) ]

df[df.isin(['banana', "apple"])]

  #         A       B      C
  #  1   apple  banana    NaN
  #  2     NaN     NaN  apple
  #  3  banana     NaN    NaN
  #  4   apple   apple    NaN

来自Divakar:返回带有两个的行

select_rows(df,['apple','banana'])

 #         A       B     C
 #   0  apple  banana  pear

相关问题 更多 >