2016-07-18 3 views
2

Ich mache einige Datenverarbeitung basierend auf einem DataFrame mit der Form (135150, 12) so doppelte Überprüfung meiner Ergebnisse manuell nicht mehr anwendbar ist.Pandas: überprüfen, ob ein Element im Dataframe ist oder eine Spalte führt zu seltsamen Ergebnissen

Ich habe ein seltsames Verhalten festgestellt, als ich nachprüfte, ob ein Element Teil des Datenrahmens oder einer bestimmten Spalte ist.

Dieses Verhalten ist mit noch kleinerem Datenrahmen reproduzierbar wie folgt:

import numpy as np 
import pandas as pd  

start = 1e-3 
end = 2e-3 
step = 0.01e-3 
arr = np.arange(start, end+step, step) 

val = 0.0019 

df = pd.DataFrame(arr, columns=['example_value']) 

print(val in df) # prints `False` 
print(val in df['example_value']) # prints `True` 
print(val in df.values) # prints `False` 
print(val in df['example_value'].values) # prints `False` 
print(df['example_value'].isin([val]).any()) # prints `False` 

Da ich ein sehr Anfänger in der Datenanalyse bin ich nicht in der Lage bin, dieses Verhalten zu erklären.

Ich weiß, dass ich verschiedene Ansätze, die verschiedenen Datentypen (wie pd.Series, np.ndarray oder np.array), um zu überprüfen, bin mit, wenn der angegebene Wert in dem Datenrahmen existiert. Zusätzlich kommt bei Verwendung der np.array oder np.ndarray die Maschinengenauigkeit ins Spiel, was mir bewusst ist.

Am Ende muss ich jedoch mehrere Funktionen implementieren, um den Datenframe zu filtern und das Vorkommen einiger Werte zu zählen, was ich zuvor mehrfach anhand boolescher Spalten in Kombination mit durchgeführten Operationen wie > und < erfolgreich durchgeführt habe.

Aber in diesem Fall muss ich nach dem genauen Wert filtern und seine Vorkommen zählen, die mich schließlich zu dem oben beschriebenen Problem führen.

Also könnte jemand erklären, was hier vor sich geht?

+1

Gleitkomma Probleme vielleicht? – Divakar

+0

@Divakar: Sicher. Das meine ich mit "Maschinengenauigkeit kommt ins Spiel". Ich weiß jedoch nicht, wie ich das in Kombination mit einem Pandas-Datenrahmen lösen soll. Mit numpy Arrays würde ich 'np.isclose()' verwenden, aber in diesem Fall arbeite ich an einem DataFrame- oder Series-Objekt, das ich sicher in numpy Objekte konvertieren könnte. Die Umwandlung in numpy Objekte und zurück zu Pandas Objekten scheint jedoch eine sehr schmutzige Lösung zu sein. – albert

+2

'val in df' prüft auf Spalten (' 'example_value' in df' gibt True zurück), 'val in df ['example_value']' prüft auf Index ('1 in df ['example_value']' gibt True zurück) Für Ihre Fall, da der Index eine ganze Zahl ist, konvertiert es das val zu Integer und überprüft dann - also die falsche positive (ein Fehler vielleicht). Der Rest scheint mit dem Fließkomma in Beziehung zu stehen. Es ist nicht notwendig, hin und her zu konvertieren, Sie können direkt np.isclose für eine Serie oder einen Datenrahmen verwenden. – ayhan

Antwort

3

Das zugrunde liegende Problem, wie Divakar vorgeschlagen hat, ist Gleitkomma-Genauigkeit. Da Datenrahmen/Serien auf der numpy gebaut werden, ist es nicht wirklich eine Strafe für obwohl numpy Methoden verwenden, so können Sie einfach etwas tun:

df['example_value'].apply(lambda x: np.isclose(x, val)).any() 

oder

np.isclose(df['example_value'], val).any() 

von denen beide korrekt zurückgeben True.

+1

Die zweite Antwort ist viel effizienter. Im Allgemeinen und insbesondere bei Verwendung von numpy-Funktionen in Pandas-Spalten ist die Anwendung um eine Größenordnung langsamer. Im obigen Beispiel ist es trivial, aber es ist etwas, auf das hingewiesen werden sollte. – DataSwede

+0

Sehr guter Punkt; Vielen Dank. Der 'apply'-Ansatz ruft' np.isclose' einmal pro Element auf, während der zweite nur einmal für die gesamte Serie aufruft. Da numpy intern viel effizienter ist als reines Python, sparen Sie viel Zeit, indem Sie nur einen einzelnen Anruf tätigen. –

Verwandte Themen