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

我正在试图确定Pandas列中是否有具有特定值的条目。我尝试用if x in df['id']来做到这一点。我认为这是工作的,除了当我给它一个值,我知道不在列43 in df['id'],它仍然返回True。当我子集到一个数据帧只包含匹配缺失id df[df['id'] == 43]的条目时,显然,其中没有条目。我如何确定在熊猫数据帧中的一列是否包含一个特定的值,为什么我目前的方法不起作用?(供参考,当我使用这个回答中的实现来解决类似的问题时,我也有同样的问题)。

703471 次浏览

in of a Series检查值是否在索引中:

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可能更有效(特别是如果你只对一个值执行此操作):

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


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

你也可以使用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

简单的条件:

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

或者使用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制作了一个关于Series的列表,而另一个我只是从常规的Series中获得一个布尔型Series,然后检查布尔型Series中是否有任何__abc4。

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 [24]: timeit 9 in x.values
666 µs ± 15.7 µs per loop (mean ± std. dev. of 7 runs, 1000 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 [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 [15]: timeit x.isin([999999]).any()
9.54 ms ± 291 µ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)

有趣的是,不管你是查找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是最快的,但也许在pandas中有更优雅的方法?

使用

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

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

假设你的数据框架是这样的:

enter image description here

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

你可以简单地写:

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

你可以试着检查一个名为“id”的列中的特定值“x”

if x in df['id'].values

使用query()找到条件包含的行,并获得带有shape[0]的行数。如果存在至少一个条目,则该语句为True:

df.query('id == 123').shape[0] > 0

我有一个CSV文件要读取:

df = pd.read_csv('50_states.csv')

在尝试之后:

if value in df.column:
print(True)

即使值在列中,它也不会输出true;

我试着:

for values in df.column:
if value == values:
print(True)
#Or do something
else:
print(False)


这工作。希望这能有所帮助!