问题:如何确定Pandas列是否包含特定值

我试图确定Pandas列中是否有一个具有特定值的条目。我试图用来做到这一点if x in df['id']。我以为这是行得通的,除非当我向它提供一个我不知道的值时,43 in df['id']它仍然返回True。当我将一个数据帧的子集仅包含与缺少的ID匹配的条目时df[df['id'] == 43],很显然,其中没有任何条目。如何确定Pandas数据框中的列是否包含特定值,为什么我的当前方法不起作用?(仅供参考,当我在类似问题的答案中使用实现时,也会遇到相同的问题)。

I am trying to determine whether there is an entry in a Pandas column that has a particular value. I tried to do this with if x in df['id']. I thought this was working, except when I fed it a value that I knew was not in the column 43 in df['id'] it still returned True. When I subset to a data frame only containing entries matching the missing id df[df['id'] == 43] there are, obviously, no entries in it. How to I determine if a column in a Pandas data frame contains a particular value and why doesn’t my current method work? (FYI, I have the same problem when I use the implementation in this answer to a similar question).


回答 0

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

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

一种选择是查看它是否具有唯一值:

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

In [22]: 'a' in s.unique()
Out[22]: True

或python集:

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

In [24]: 'a' in set(s)
Out[24]: True

正如@DSM所指出的那样,直接在这些值上使用可能会更有效(尤其是如果您只对一个值执行此操作):

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

In [32]: 'a' in s.values
Out[32]: True

in of a Series checks whether the value is in the index:

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

One option is to see if it’s in unique values:

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

In [22]: 'a' in s.unique()
Out[22]: True

or a python set:

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

In [24]: 'a' in set(s)
Out[24]: True

As pointed out by @DSM, it may be more efficient (especially if you’re just doing this for one value) to just use in directly on the values:

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

In [32]: 'a' in s.values
Out[32]: True

回答 1

您也可以使用pandas.Series.isin,尽管它比'a' in s.values以下内容长一些:

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

但是,如果您需要一次为一个DataFrame匹配多个值,则这种方法可以更加灵活(请参阅DataFrame.isin

>>> df = DataFrame({'A': [1, 2, 3], 'B': [1, 4, 7]})
>>> df.isin({'A': [1, 3], 'B': [4, 7, 12]})
       A      B
0   True  False  # Note that B didn't match 1 here.
1  False   True
2   True   True

You can also use pandas.Series.isin although it’s a little bit longer than 'a' in s.values:

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

But this approach can be more flexible if you need to match multiple values at once for a DataFrame (see DataFrame.isin)

>>> df = DataFrame({'A': [1, 2, 3], 'B': [1, 4, 7]})
>>> df.isin({'A': [1, 3], 'B': [4, 7, 12]})
       A      B
0   True  False  # Note that B didn't match 1 here.
1  False   True
2   True   True

回答 2

found = df[df['Column'].str.contains('Text_to_search')]
print(found.count())

found.count()遗嘱中含有的比赛数量

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

found = df[df['Column'].str.contains('Text_to_search')]
print(found.count())

the found.count() will contains number of matches

And if it is 0 then means string was not found in the Column.


回答 3

我做了一些简单的测试:

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语法似乎需要花费相同的时间(必须使用二进制搜索)

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)

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

I did a few simple tests:

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)

Interestingly it doesn’t matter if you look up 9 or 999999, it seems like it takes about the same amount of time using the in syntax (must be using binary search)

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)

Seems like using x.values is the fastest, but maybe there is a more elegant way in pandas?


回答 4

或使用Series.tolistSeries.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列出一个有关a的列表Series,而另一个我只是Series从常规中获取一个布尔值Series,然后检查布尔值中是否有任何Trues Series

Or use Series.tolist or 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 makes a list about of a Series, and the other one i am just getting a boolean Series from a regular Series, then checking if there are any Trues in the boolean Series.


回答 5

简单条件:

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

Simple condition:

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

回答 6

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

如果x存在,id则返回存在的索引列表,否则给出一个空列表。

Use

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

If x is present in id then it’ll return the list of indices where it is present, else it gives an empty list.


回答 7

我不建议使用“串联值”,否则可能导致许多错误。请查看此答案以获取详细信息:在Pandas系列中与运算符一起使用

I don’t suggest to use “value in series”, which can lead many errors. Please see this answer for detail: Using in operator with Pandas series


回答 8

假设您的数据框看起来像:

在此处输入图片说明

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

您可以简单地写:

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

Suppose you dataframe looks like :

enter image description here

Now you want to check if filename “80900026941984” is present in the dataframe or not.

You can simply write :

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

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。