it-swarm.com.de

So bestimmen Sie, ob eine Pandas-Spalte einen bestimmten Wert enthält

Ich versuche zu ermitteln, ob es in einer Pandas-Spalte einen Eintrag gibt, der einen bestimmten Wert hat. Ich habe versucht, dies mit if x in df['id'] zu tun. Ich dachte, dass dies funktionierte, außer wenn ich einen Wert eingegeben habe, von dem ich wusste, dass er nicht in der Spalte 43 in df['id'] steht, gab er trotzdem True zurück. Wenn ich Teil eines Datenrahmens bin, der nur Einträge enthält, die mit der fehlenden ID df[df['id'] == 43] übereinstimmen, gibt es offensichtlich keine Einträge. Wie kann ich feststellen, ob eine Spalte in einem Pandas-Datenrahmen einen bestimmten Wert enthält und warum funktioniert meine aktuelle Methode nicht? (FYI, ich habe das gleiche Problem, wenn ich die Implementierung in dieser Antwort zu einer ähnlichen Frage verwende).

81
Michael

in einer Serie überprüft, ob der Wert im Index enthalten ist:

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

Eine Option ist zu sehen, ob es in unique values ​​ist:

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

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

oder ein Python-Set:

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

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

Wie von @DSM ausgeführt, ist es möglicherweise effizienter (insbesondere wenn Sie dies nur für einen Wert tun), wenn Sie die Werte direkt verwenden:

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

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

Sie können auch pandas.Series.isin verwenden, obwohl es etwas länger ist als '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

Dieser Ansatz kann jedoch flexibler sein, wenn Sie für einen DataFrame mehrere Werte gleichzeitig abgleichen müssen (siehe 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

Oder benutze Series.tolist oder 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 macht eine Liste über eine Series, und die andere, ich bekomme nur eine boolesche Series aus einer regulären Series, und dann prüfe, ob es Trues in der booleschen Series gibt.

1
U9-Forward

Benutzen

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

Wenn x in id vorhanden ist, wird die Liste der Indizes zurückgegeben, in denen sie vorhanden ist, andernfalls wird eine leere Liste ausgegeben.

1
Ramana Sriwidya

Einfache Bedingung:

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

Ich habe ein paar einfache Tests gemacht:

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)

Interessanterweise spielt es keine Rolle, ob Sie 9 oder 999999 nachschlagen, es scheint, als würde die Verwendung der In-Syntax ungefähr dieselbe Zeit in Anspruch nehmen (muss die binäre Suche verwenden).

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)

Scheint, als ob die Verwendung von x.values ​​am schnellsten ist, aber vielleicht gibt es einen eleganteren Weg bei Pandas?

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

der found.count() enthält die Anzahl der Übereinstimmungen und wenn

Wenn es 0 ist, bedeutet dies, dass in der Spalte kein String gefunden wurde.

0
Shahir Ansari

Ich schlage nicht vor, "Wert in Serie" zu verwenden, was zu vielen Fehlern führen kann. Weitere Informationen finden Sie in dieser Antwort: Verwendung in Operator mit der Pandas-Serie

0
Vicky Ding