パンダ列に特定の値が含まれているかどうかを確認する方法


156

Pandas列に特定の値を持つエントリがあるかどうかを確認しようとしています。私はでこれをやろうとしましたif x in df['id']。私はこれが機能していると思いましたが、列に含まれていないことがわかっている値を入力した場合は、43 in df['id']それでも返されTrueます。欠落しているID df[df['id'] == 43]に一致するエントリのみを含むデータフレームにサブセット化すると、明らかに、そこにエントリがありません。Pandasデータフレームの列に特定の値が含まれているかどうかを確認する方法と、現在のメソッドが機能しないのはなぜですか?(ちなみに、私が同じような質問に対するこの回答の実装を使用すると、同じ問題が発生します)。

回答:


183

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

1つのオプションは、一意の値であるかどうかを確認することです。

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で指摘されているように、(特に1つの値に対してこれを実行している場合は)値を直接使用する方が効率的です。

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

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

2
一意であるかどうかは知りたくありません。主にそこにあるかどうかを知りたいです。
Michael

24
'a' in s.values長いシリーズの方が速いと思います。
DSM

4
@AndyHayden 'a' in sパンダが系列の値ではなくインデックスをチェックする理由を知っていますか?辞書ではキーをチェックしますが、pandasシリーズはリストや配列のように動作するはずです。
レイ

3
pandas 0.24.0以降、s.valuesおよびを使用すると、df.values非常に非推奨になります。参照してくださいこれを。また、s.values場合によっては実際にははるかに遅くなります。
Qusai Alothman、

1
@QusaiAlothmanはどちらでもない.to_numpy.array、シリーズで利用できないため、どの代替案が推奨されているのか完全にはわかりません(「非常に非推奨」とは読みません)。実際、彼らは.valuesがnumpy配列を返さないかもしれないと言っています、例えばカテゴリカルの場合...しかし、inそれでも期待どおりに機能するので問題ありません(実際、それはより効率的にnumpy配列の対応物です)
Andy Hayden

27

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()
thando

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

found.count()意志が一致の数が含まれています

そして、それが0の場合、列に文字列が見つからなかったことを意味します。


2
私のために働いたが、私はカウントを取得するためにlen(found)を使用した
kztd

1
はいlen(found)はやや良いオプションです。
Shahir Ansari、

1
このアプローチは、私のために働いたが、私はパラメータを含める必要がありましたna=Falseし、regex=False私のユースケースのために、のようにここで説明:pandas.pydata.org/pandas-docs/stable/reference/api/...
マビン

1
しかしstring.containsは部分文字列検索を行います。例:「head_hunter」という値が存在する場合。str。で "head"を渡すと一致が含まれ、Trueが返されますが、これは誤りです。
karthikeyan

@karthikeyan間違いではありません。検索のコンテキストによって異なります。住所や製品を検索する場合はどうでしょうか。説明に合うすべての製品が必要です。
Shahir Ansari

6

私はいくつかの簡単なテストを行いました:

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を使用するのが最も速いようですが、パンダにはもっとエレガントな方法があるのでしょうか?


結果の順序を最小から最大に変更すると素晴らしいでしょう。よくやった!
smm

4

または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、もう1つSeriesは通常からブール値を取得し、ブール値にs Seriesがあるかどうかを確認します。TrueSeries


1

単純な条件:

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

1

使用する

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

xが存在する場合は、存在するidインデックスのリストを返し、それ以外の場合は空のリストを返します。



0

データフレームが次のようになっているとします。

ここに画像の説明を入力してください

次に、ファイル名「80900026941984」がデータフレームに存在するかどうかを確認します。

あなたは単に書くことができます:

if sum(df["filename"].astype("str").str.contains("80900026941984")) > 0:
    print("found")
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.