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

Posted

技术标签:

【中文标题】如何确定 Pandas 列是不是包含特定值【英文标题】:How to determine whether a Pandas Column contains a particular value如何确定 Pandas 列是否包含特定值 【发布时间】:2014-02-14 16:40:46 【问题描述】:

我正在尝试确定 Pandas 列中是否存在具有特定值的条目。我试图用if x in df['id'] 来做到这一点。我认为这是可行的,除非我给它提供了一个我知道不在列 43 in df['id'] 中的值,它仍然返回 True。当我对仅包含与缺少的 id df[df['id'] == 43] 匹配的条目的数据框进行子集时,显然其中没有条目。如何确定 Pandas 数据框中的列是否包含特定值,为什么我当前的方法不起作用? (仅供参考,当我将这个answer 中的实现用于类似问题时,我遇到了同样的问题)。

【问题讨论】:

【参考方案1】:

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

一种选择是查看它是否在unique 值中:

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

【讨论】:

我不想知道它是否一定是唯一的,主要是想知道它是否存在。 我认为 'a' in s.values 对于长系列应该更快。 @AndyHayden 你知道为什么对于'a' in s,pandas 选择检查索引而不是序列的值吗?在字典中他们检查键,但熊猫系列应该更像一个列表或数组,不是吗? 从 pandas 0.24.0 开始,使用 s.valuesdf.values 是非常不受欢迎的。见this。此外,s.values 在某些情况下实际上要慢得多。 @QusaiAlothman 既不是.to_numpy 也不是.array 在系列中可用,所以我不完全确定他们提倡什么替代方案(我没有读到“非常气馁”)。事实上,他们说 .values 可能不会返回一个 numpy 数组,例如在分类的情况下......但这很好,因为in 仍然可以按预期工作(实际上比它的 numpy 数组对应物更有效)【参考方案2】:

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

【讨论】:

你也可以使用DataFrame.any()函数:s.isin(['a']).any()【参考方案3】:
found = df[df['Column'].str.contains('Text_to_search')]
print(found.count())

found.count() 将包含匹配数

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

【讨论】:

为我工作,但我使用 len(found) 来获取计数 是的 len(found) 是一个更好的选择。 这种方法对我有用,但我必须为我的用例包含参数 na=Falseregex=False,如下所述:pandas.pydata.org/pandas-docs/stable/reference/api/… 但是 string.contains 会进行子字符串搜索。例如:如果存在名为“head_hunter”的值。在 str.contains 中传递“head”匹配并给出错误的 True。 @karthikeyan 它没有错。取决于您的搜索上下文。如果您正在搜索地址或产品怎么办。您需要符合描述的所有产品。【参考方案4】:

我做了一些简单的测试:

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 中有更优雅的方式?

【讨论】:

如果您将结果的顺序从最小到最大更改,那就太好了。干得好!【参考方案5】:

或者使用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,然后检查布尔值@ 中是否有Trues 987654329@.

【讨论】:

【参考方案6】:

您可以尝试检查名为“id”的特定列中的特定值“x”

if x in df['id'].values

【讨论】:

【参考方案7】:

简单条件:

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

【讨论】:

【参考方案8】:

使用

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

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

【讨论】:

【参考方案9】:

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

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

你可以简单地写:

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

【讨论】:

以上是关于如何确定 Pandas 列是不是包含特定值的主要内容,如果未能解决你的问题,请参考以下文章

C# - 确定 IP 地址范围是不是包含特定地址

包含 Pandas 的新列中包含列表的值计数 [重复]

如何确定 XElement.Elements() 是不是包含具有特定名称的节点?

如何改进评估列表以确定它是不是包含特定连续项目的方法?

Swift:确定自定义对象数组是不是包含特定字符串[重复]

用于确定 JSON 值是不是包含指定属性的 SQL 查询