it-swarm.com.de

Ersetzen Sie ungültige Werte durch Keine in Pandas DataFrame

Gibt es eine Methode zum Ersetzen von Werten durch None in Pandas in Python?

Sie können df.replace('pre', 'post') verwenden und einen Wert durch einen anderen ersetzen. Dies ist jedoch nicht möglich, wenn Sie den Wert None verwenden möchten. Wenn Sie dies versuchen, erhalten Sie ein seltsames Ergebnis.

Also 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)

das ein folgendes Ergebnis liefert:

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 ein so seltsames Ergebnis zurückgegeben?

Da ich diesen Datenrahmen in die MySQL-Datenbank einfügen möchte, kann ich in keinem Element meines Datenrahmens NaN Werte einfügen und möchte stattdessen None einfügen. Sicherlich können Sie zuerst '-' In NaN ändern und dann NaN in None konvertieren, aber ich möchte wissen, warum sich der Datenrahmen so schrecklich verhält .

Getestet auf pandas 0.12.0 dev auf Python 2.7 und OS X 10.8. Python ist eine vorinstallierte Version auf OS X und ich haben zu Ihrer Information pandas mithilfe des SciPy Superpack-Skripts installiert.

64
Blaszard

In späteren Versionen von pandas ergibt dies einen TypeError:

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
88
Andy Hayden

where ist wahrscheinlich das, wonach Sie suchen. So

data=data.where(data=='-', None) 

Aus dem Panda Docs :

where [gibt ein Objekt zurück, das dieselbe Form wie self hat und dessen entsprechende Einträge von self stammen, wobei cond True und andernfalls von other ist).

14
user2966041

Ich bevorzuge die Lösung mit replace mit einem dict 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.

11
Michael Dorner

Bevor Sie mit diesem Beitrag fortfahren, ist es wichtig, dass Sie den Unterschied zwischen NaN und None verstehen. Einer ist ein Float-Typ, der andere ist ein Objekttyp. Pandas ist besser für die Arbeit mit skalaren Typen geeignet, da viele Methoden für diese Typen vektorisiert werden können. Pandas versucht, None und NaN konsistent zu behandeln, NumPy jedoch nicht .

Mein Vorschlag ( nd Andys ) ist, bei NaN zu bleiben.

(v0.24 +) Eine bessere Lösung für CSV/Excel-Daten: na_values=['-']

Wenn Sie diese Daten aus CSV/Excel geladen haben, habe ich gute Nachrichten für Sie. Sie können dies beim Laden der Daten im Stammverzeichnis unterdrücken, anstatt als nächsten Schritt einen Fix mit Code schreiben zu müssen.

Die meisten von den pd.read_* Funktionen (wie read_csv und read_Excel ) akzeptiere ein na_values Attribut.

file.csv

A,B
-,1
3,-
2,-
5,3
1,-2
-5,4
-1,-1
-,0
9,0

Nun, um die - Zeichen in NaNs, do,

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.

P.S .: In v0.24 + können Sie den Integer-Typ auch dann beibehalten, wenn Ihre Spalte NaNs enthält (ja, sprechen Sie darüber, den Kuchen zu haben und ihn auch zu essen). Sie können 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 Optionen.


Umgang mit numerischen Daten: pd.to_numeric mit errors='coerce

Wenn Sie mit numerischen Daten arbeiten, ist die Verwendung von pd.to_numeric mit dem errors='coerce' Argument, das ungültige Werte (Werte, die nicht in numerische Werte umgewandelt werden können) in NaN umwandelt.

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) Integer-D-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 apply, um mehrere Spalten zu erzwingen:

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 ordne das Ergebnis danach wieder zu.

Weitere Informationen finden Sie in diese Antwort .

3
cs95
df = pd.DataFrame(['-',3,2,5,1,-5,-1,'-',9])
df = df.where(df!='-', None)
2
Shravan kp

Das Setzen von Nullwerten kann mit np.nan Erfolgen:

import numpy as np
df.replace('-', np.nan)

Vorteil ist, dass df.last_valid_index() diese als ungültig erkennt.

0