Python 如何确定列是否包含特定值

Python 如何确定列是否包含特定值,python,pandas,Python,Pandas,我试图确定Pandas列中是否有具有特定值的条目。我试着用df['id']中的x来实现这一点。我认为这是可行的,但当我给它输入一个我知道不在df['id']的43列中的值时,它仍然返回True。当我将一个子集设置为仅包含与缺少的id匹配的条目的数据帧时,df[df['id']==43]显然,其中没有条目。如何确定Pandas数据框中的列是否包含特定值,以及为什么当前方法不起作用?(仅供参考,当我使用本节中的实现解决类似问题时,我也会遇到同样的问题)。在系列的中检查值是否在索引中: In [11]

我试图确定Pandas列中是否有具有特定值的条目。我试着用df['id']中的x来实现这一点。我认为这是可行的,但当我给它输入一个我知道不在df['id']的
43列中的值时,它仍然返回
True
。当我将一个子集设置为仅包含与缺少的id匹配的条目的数据帧时,
df[df['id']==43]
显然,其中没有条目。如何确定Pandas数据框中的列是否包含特定值,以及为什么当前方法不起作用?(仅供参考,当我使用本节中的实现解决类似问题时,我也会遇到同样的问题)。

在系列的
中检查值是否在索引中:

In [11]: s = pd.Series(list('abc'))

In [12]: s
Out[12]: 
0    a
1    b
2    c
dtype: object

In [13]: 1 in s
Out[13]: True

In [14]: 'a' in s
Out[14]: False
一个选项是查看它是否在值中:

或python集:

In [23]: set(s)
Out[23]: {'a', 'b', 'c'}

In [24]: 'a' in set(s)
Out[24]: True
正如@DSM所指出的,直接在值上使用in可能更有效(特别是如果您只为一个值执行此操作):

In [31]: s.values
Out[31]: array(['a', 'b', 'c'], dtype=object)

In [32]: 'a' in s.values
Out[32]: True
您也可以使用,尽管它比s.values中的
'a'长一点:

In [2]: s = pd.Series(list('abc'))

In [3]: s
Out[3]: 
0    a
1    b
2    c
dtype: object

In [3]: s.isin(['a'])
Out[3]: 
0    True
1    False
2    False
dtype: bool

In [4]: s[s.isin(['a'])].empty
Out[4]: False

In [5]: s[s.isin(['z'])].empty
Out[5]: True
但是,如果您需要为一个数据帧同时匹配多个值,那么这种方法会更加灵活(请参阅)

简单条件:

if any(str(elem) in ['a','b'] for elem in df['column'].tolist()):

或者使用
Series.tolist
Series.any

>>> s = pd.Series(list('abc'))
>>> s
0    a
1    b
2    c
dtype: object
>>> 'a' in s.tolist()
True
>>> (s=='a').any()
True
Series.tolist
列出了一个关于
系列
的列表,另一个我只是从一个常规的
系列
中得到一个布尔
系列
,然后检查布尔
系列
中是否有
s

found = df[df['Column'].str.contains('Text_to_search')]
print(found.count())
found.count()
将包含匹配数


如果为0,则表示在列中找不到字符串。

我做了一些简单的测试:

In [10]: x = pd.Series(range(1000000))

In [13]: timeit 999999 in x.values
567 µs ± 25.6 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [15]: timeit x.isin([999999]).any()
9.54 ms ± 291 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [16]: timeit (x == 999999).any()
6.86 ms ± 107 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [17]: timeit 999999 in set(x)
79.8 ms ± 1.98 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [21]: timeit x.eq(999999).any()
7.03 ms ± 33.7 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [22]: timeit x.eq(9).any()
7.04 ms ± 60 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [24]: timeit 9 in x.values
666 µs ± 15.7 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
有趣的是,查找9或999999并不重要,似乎使用in语法所需的时间大致相同(必须使用二进制搜索)

似乎使用x.values是最快的,但也许在pandas中有一种更优雅的方式?

使用

df[df['id']==x].index.tolist()

如果
x
出现在
id
中,那么它将返回它所在的索引列表,否则它将给出一个空列表。

假设您的数据帧如下所示:

现在,您需要检查数据帧中是否存在文件名“80900026941984”

你可以简单地写:

if sum(df["filename"].astype("str").str.contains("80900026941984")) > 0:
    print("found")

我不想知道它是否一定是唯一的,主要是我想知道它是否存在。我认为s.values
中的
'a'对于长系列应该更快。@yHayden你知道为什么s
中的
'a'选择检查索引而不是系列的值吗?在字典中,他们检查键,但熊猫系列应该更像一个列表或数组,否?从熊猫0.24.0开始,使用
s.values
df.values
是非常不一致的。看见另外,
s.values
在某些情况下实际上要慢得多。@Qusailothman无论是
.to\u numpy
还是
.array
都可以在一个系列中找到,所以我不完全确定他们在提倡什么替代方案(我没有读到“高度劝阻”)。事实上,他们说。值可能不会返回numpy数组,例如,在分类数组的情况下。。。但这很好,因为
中的
仍将按预期工作(确实比numpy数组的对应项更有效),但我使用了len(find)来获取countYes len(find)是一个更好的选择。这种方法对我有效,但我必须在我的用例中包含参数
na=False
regex=False
,正如这里所解释的:但是string.contains执行子字符串搜索。例如:如果存在名为“head_hunter”的值。在str.中传递“head”包含匹配项,并给出错误的True。@karthikeyan它没有错。取决于搜索的上下文。如果您正在搜索地址或产品,该怎么办。您需要所有符合描述的产品。如果您将结果的顺序从最小更改为最大,那就太好了。干得好!您还可以使用函数:
s.isin(['a']).any()
In [24]: timeit 9 in x.values
666 µs ± 15.7 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [25]: timeit 9999 in x.values
647 µs ± 5.21 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [26]: timeit 999999 in x.values
642 µs ± 2.11 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [27]: timeit 99199 in x.values
644 µs ± 5.31 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [28]: timeit 1 in x.values
667 µs ± 20.8 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
df[df['id']==x].index.tolist()
if sum(df["filename"].astype("str").str.contains("80900026941984")) > 0:
    print("found")