如何确定 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.values
和 df.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=False
和 regex=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.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
列出了一个Series
的列表,而另一个我只是从普通的Series
得到一个布尔值Series
,然后检查布尔值@ 中是否有True
s 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 列是不是包含特定值的主要内容,如果未能解决你的问题,请参考以下文章