web-dev-qa-db-fra.com

Comment déterminer si une colonne de pandas contient une valeur particulière

J'essaie de déterminer s'il y a une entrée dans une colonne Pandas qui a une valeur particulière. J'ai essayé de faire cela avec if x in df['id']. Je pensais que cela fonctionnait, sauf que lorsque je l'ai alimentée, une valeur que je savais ne se trouvait pas dans la colonne 43 in df['id'] mais qui retournait toujours True. Lorsque je sous-ensembles d'un cadre de données contenant uniquement des entrées correspondant à l'identifiant manquant df[df['id'] == 43], il n'y a évidemment aucune entrée. Comment déterminer si une colonne d'un bloc de données Pandas contient une valeur particulière et pourquoi ma méthode actuelle ne fonctionne-t-elle pas? (Pour info, j'ai le même problème lorsque j'utilise l'implémentation dans cette réponse à une question similaire).

81
Michael

in of Series vérifie si la valeur est dans l'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

Une option est de voir si c'est dans unique values:

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

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

ou un ensemble de python:

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

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

Comme l'a souligné @DSM, il peut être plus efficace (surtout si vous ne le faites que pour une valeur) d'utiliser directement dans les valeurs:

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

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

Vous pouvez également utiliser pandas.Series.isin bien qu’il soit un peu plus long que '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

Mais cette approche peut être plus flexible si vous devez faire correspondre plusieurs valeurs à la fois pour un DataFrame (voir 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
17
ffeast

Ou utilisez Series.tolist ou 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 fait une liste d'environ Series, et l'autre, je reçois juste un booléen Series à partir d'un Series normal, puis vérifie s'il existe un Trues dans le booléen Series.

1
U9-Forward

Utilisation

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

Si x est présent dans id alors il retournera la liste des index où il est présent, sinon il donnera une liste vide.

1
Ramana Sriwidya

Condition simple:

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

J'ai fait quelques tests simples:

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)

Fait intéressant, peu importe si vous recherchez 9 ou 999999, il semble que cela prend à peu près le même temps en utilisant la syntaxe in (vous devez utiliser la recherche binaire).

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)

On dirait que l'utilisation de x.values ​​est la plus rapide, mais peut-être y a-t-il un moyen plus élégant dans les pandas?

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

le found.count() contient le nombre de résultats

Et s'il vaut 0, cela signifie que la chaîne n'a pas été trouvée dans la colonne.

0
Shahir Ansari

Je ne suggère pas d'utiliser "valeur en série", ce qui peut entraîner de nombreuses erreurs. Veuillez consulter cette réponse pour plus de détails: Utilisation de l’opérateur in avec les séries Pandas

0
Vicky Ding