Gibt es eine Methode, durch die Werte None
in Pandas in Python ersetzt werden können?
Sie können df.replace('pre', 'post')
einen Wert verwenden und durch einen anderen ersetzen. Dies ist jedoch nicht möglich, wenn Sie ihn durch einen Wert ersetzen möchten. None
Wenn Sie dies versuchen, erhalten Sie ein seltsames Ergebnis.
Hier ist ein Beispiel:
df = DataFrame(['-',3,2,5,1,-5,-1,'-',9])
df.replace('-', 0)
was ein erfolgreiches Ergebnis zurückgibt.
Aber,
df.replace('-', None)
Dies ergibt ein folgendes Ergebnis:
0
0 - // this isn't replaced
1 3
2 2
3 5
4 1
5 -5
6 -1
7 -1 // this is changed to `-1`...
8 9
Warum wird so ein seltsames Ergebnis zurückgegeben?
Da ich diesen Datenrahmen in die MySQL-Datenbank einfügen möchte, kann ich keine NaN
Werte in ein Element in meinem Datenrahmen einfügen und möchte stattdessen Werte einfügen None
. Sicherlich können Sie zuerst ändern konvertieren und dann zu , aber ich möchte wissen , warum die Datenrahmen in einer solchen schreckliche Art und Weise wirkt.'-'
NaN
NaN
None
Getestet auf Pandas 0.12.0 Dev unter Python 2.7 und OS X 10.8. Python ist eine vorinstallierte Version unter OS X, und ich habe Pandas zu Ihrer Information mithilfe des SciPy Superpack-Skripts installiert.
write_frame
nichtNaN
s zunone
s?InternalError: (1054, u"Unknown column 'nan' in 'field list'")
Fehler. Ich weiß nicht , über alle Lösungen , die auf sie andere als die UmwandlungNaN
zuNone
vor der Ausführungwrite_frame
Verfahren.na_values
Arguments als NaN einlesen . Weitere Informationen in dieser Antwort.Antworten:
In späteren Versionen von Pandas wird dies einen TypeError ergeben:
df.replace('-', None) TypeError: If "to_replace" and "value" are both None then regex must be a mapping
Sie können dies tun, indem Sie entweder eine Liste oder ein Wörterbuch übergeben:
In [11]: df.replace('-', df.replace(['-'], [None]) # or .replace('-', {0: None}) Out[11]: 0 0 None 1 3 2 2 3 5 4 1 5 -5 6 -1 7 None 8 9
Ich empfehle jedoch die Verwendung von NaNs anstelle von None:
In [12]: df.replace('-', np.nan) Out[12]: 0 0 NaN 1 3 2 2 3 5 4 1 5 -5 6 -1 7 NaN 8 9
quelle
df.replace(['-'], [None])
oderdf.replace({'-': None})
, denke ich. Die VerwendungNone
als Sentinel schließt die Verwendung als Wert aus.df
wie zu sich selbst zurück:df = df.replace({'?': np.nan})
df.replace('-', df.replace(['-'], [None])
sieht funky aus, ist das ein Tippfehler?Ich bevorzuge die Lösung
replace
mit einemdict
wegen seiner Einfachheit und Eleganz:df.replace({'-': None})
Sie können auch mehr Ersatz haben:
df.replace({'-': None, 'None': None})
Und selbst bei größeren Ersetzungen ist immer klar und deutlich, was durch was ersetzt wird - was meiner Meinung nach für lange Listen viel schwieriger ist.
quelle
dict
Typs in dazu führt,to_replace
dass dermethod
Parameter nicht ausgewertet wird und dermethod='pad'
Standardwert daher keine negativen Auswirkungen hat.where
ist wahrscheinlich das, wonach Sie suchen. Damitdata=data.where(data=='-', None)
Aus den Panda-Dokumenten :
quelle
Bevor Sie mit diesem Beitrag fortfahren, ist es wichtig, den Unterschied zwischen NaN und None zu verstehen . Einer ist ein Float-Typ, der andere ist ein Objekttyp. Pandas eignet sich besser für die Arbeit mit Skalartypen, da viele Methoden für diese Typen vektorisiert werden können. Pandas versucht zwar, None und NaN konsistent zu behandeln, NumPy jedoch nicht.
Mein Vorschlag ( und der von Andy ) ist, bei NaN zu bleiben.
Aber um Ihre Frage zu beantworten ...
pandas> = 0.18:
na_values=['-']
Argument mit verwendenread_csv
Wenn Sie diese Daten aus CSV / Excel geladen haben, habe ich gute Nachrichten für Sie. Sie können dies während des Ladens der Daten im Stammverzeichnis löschen, anstatt als nachfolgenden Schritt einen Fix mit Code schreiben zu müssen.
Die meisten
pd.read_*
Funktionen (wieread_csv
undread_excel
) akzeptieren einna_values
Attribut.file.csv
A,B -,1 3,- 2,- 5,3 1,-2 -5,4 -1,-1 -,0 9,0
-
Um die Zeichen in NaNs umzuwandeln, tun Sie Folgendes:import pandas as pd df = pd.read_csv('file.csv', na_values=['-']) df A B 0 NaN 1.0 1 3.0 NaN 2 2.0 NaN 3 5.0 3.0 4 1.0 -2.0 5 -5.0 4.0 6 -1.0 -1.0 7 NaN 0.0 8 9.0 0.0
Ähnliches gilt für andere Funktionen / Dateiformate.
PS: In Version 0.24 + können Sie den Integer-Typ beibehalten, auch wenn Ihre Spalte NaNs enthält (ja, sprechen Sie davon, den Kuchen zu haben und ihn auch zu essen). Sie können angeben
dtype='Int32'
df = pd.read_csv('file.csv', na_values=['-'], dtype='Int32') df A B 0 NaN 1 1 3 NaN 2 2 NaN 3 5 3 4 1 -2 5 -5 4 6 -1 -1 7 NaN 0 8 9 0 df.dtypes A Int32 B Int32 dtype: object
Der dtype ist kein herkömmlicher int-Typ ... sondern ein nullable Integer Type. Es gibt andere Möglichkeiten.
Umgang mit numerischen Daten:
pd.to_numeric
miterrors='coerce
Wenn Sie mit numerischen Daten arbeiten, besteht eine schnellere Lösung darin,
pd.to_numeric
daserrors='coerce'
Argument zu verwenden, das ungültige Werte (Werte, die nicht in numerische Werte umgewandelt werden können) zu NaN zwingt.pd.to_numeric(df['A'], errors='coerce') 0 NaN 1 3.0 2 2.0 3 5.0 4 1.0 5 -5.0 6 -1.0 7 NaN 8 9.0 Name: A, dtype: float64
Verwenden Sie, um den (nullbaren) ganzzahligen Typ beizubehalten
pd.to_numeric(df['A'], errors='coerce').astype('Int32') 0 NaN 1 3 2 2 3 5 4 1 5 -5 6 -1 7 NaN 8 9 Name: A, dtype: Int32
Verwenden Sie zum Erzwingen mehrerer Spalten
apply
:df[['A', 'B']].apply(pd.to_numeric, errors='coerce').astype('Int32') A B 0 NaN 1 1 3 NaN 2 2 NaN 3 5 3 4 1 -2 5 -5 4 6 -1 -1 7 NaN 0 8 9 0
... und ordnen Sie das Ergebnis danach wieder zu.
Weitere Informationen finden Sie in dieser Antwort .
quelle
df = pd.DataFrame(['-',3,2,5,1,-5,-1,'-',9]) df = df.where(df!='-', None)
quelle
Das Setzen von Nullwerten kann erfolgen mit
np.nan
:import numpy as np df.replace('-', np.nan)
Vorteil ist, dass
df.last_valid_index()
diese als ungültig erkannt werden.quelle
Verwenden von Ersetzen und Zuweisen eines neuen df:
import pandas as pd df = pd.DataFrame(['-',3,2,5,1,-5,-1,'-',9]) dfnew = df.replace('-', 0) print(dfnew) (venv) D:\assets>py teste2.py 0 0 0 1 3 2 2 3 5 4 1 5 -5
quelle
df.replace('-', np.nan).astype("object")
Dadurch wird sichergestellt, dass Sie
isnull()
Ihren Datenrahmen später verwenden könnenquelle
Mit Pandas Version ≥1.0.0 würde ich verwenden
DataFrame.replace
oderSeries.replace
:df.replace(old_val, pd.NA, inplace=True)
Dies ist aus zwei Gründen besser:
pd.NA
anstelle vonNone
odernp.nan
.quelle