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).
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
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
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 True
s dans le booléen Series
.
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.
Condition simple:
if any(str(elem) in ['a','b'] for elem in df['column'].tolist()):
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?
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.
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