2015-11-18 4 views
11

Ich lese eine CSV-Datei in einen DataFrame. Ich muss Whitespace von allen String-ähnlichen Zellen entfernen und die anderen Zellen in Python 2.7 unverändert lassen.Pythonischer/effizienter Weg Whitespace von jeder Pandas Data Frame Zelle zu entfernen, die ein stringähnliches Objekt enthält

Hier ist, was ich tue:

def remove_whitespace(x): 
    if isinstance(x, basestring): 
     return x.strip() 
    else: 
     return x 

my_data = my_data.applymap(remove_whitespace) 

Gibt es eine bessere oder mehr idiomatische zu Pandas Art und Weise, dies zu tun?

Gibt es einen effizienteren Weg (vielleicht, indem man die Dinge spaltenweise macht)?

Ich habe versucht, nach einer endgültigen Antwort zu suchen, aber die meisten Fragen zu diesem Thema scheinen zu sein, Whitespace von den Spaltennamen selbst zu streichen, oder davon auszugehen, dass die Zellen alle Zeichenfolgen sind.

+0

Was würde passieren, wenn Sie x.strip() für ein Element, das keine Instanz eines Basestrings ist, machen würden? Wenn es keine Nachteile gibt, könnten Sie den Scheck entfernen und ihn durch einen Versuchs- und Ausnahme-Block ersetzen. Das könnte die Dinge beschleunigen. –

+2

Verwenden Sie 'pandas.read_csv' (http://pandas.pydata.org/pandas-docs/version/0.17.0/generated/pandas.read_csv.html)? Hast du 'skipinitialspace = True' probiert? –

+0

@WarrenWeckesser Ich könnte Whitespace sowohl vor als auch nach den Daten haben, die ich in der Zelle interessiere, also denke ich, dass Skipinitialspace nur die Hälfte des Problems behebt. – deadcode

Antwort

16

Sie Pandas Series.str.strip() Methode, dies für jede strangartige Säule schnell zu tun verwenden:

>>> data = pd.DataFrame({'values': [' ABC ', ' DEF', ' GHI ']}) 
>>> data 
     values 
0  ABC 
1  DEF 
2  GHI 

>>> data['values'].str.strip() 
0 ABC 
1 DEF 
2 GHI 
Name: values, dtype: object 
3

Wenn Sie pandas.read_csv aufrufen, können Sie einen regulären Ausdruck verwenden, die durch ein Komma null oder mehrere Leerzeichen Spiele gefolgt von null oder mehr Leerzeichen als Trennzeichen.

Zum Beispiel, hier ist "data.csv":

In [19]: !cat data.csv 
1.5, aaa, bbb , ddd  , 10 , XXX 
2.5, eee, fff ,  ggg, 20 ,  YYY 

(Die erste Zeile endet mit drei Räumen nach XXX, während die zweite Zeile in der letzten Y endet.)

Im Folgenden verwendet pandas.read_csv() die lesen Dateien mit dem regulären Ausdruck ' *, *' als Trennzeichen. (Mit einem regulären Ausdruck als das Trennzeichen nur in dem „Python“ Motor read_csv() ist.)

In [20]: import pandas as pd 

In [21]: df = pd.read_csv('data.csv', header=None, delimiter=' *, *', engine='python') 

In [22]: df 
Out[22]: 
    0 1 2 3 4 5 
0 1.5 aaa bbb ddd 10 XXX 
1 2.5 eee fff ggg 20 YYY 
+1

beantwortet Dies ist sehr nahe, aber hat ein Problem mit quotierten Eingabewerten wie dem folgenden: "a, b, c", d Es kann nicht die Leerzeichen aus dem ersten Feld ziehen, die ich in der Zelle des Datenrahmens als 'a, b, c' gespeichert werden wollte – deadcode

1

Den „data [‚Werte‘]. Str.strip()“ oben Antwort nicht für mich arbeiten , aber ich habe eine einfache Arbeit gefunden. Ich bin mir sicher, dass es einen besseren Weg dafür gibt. Die Funktion str.strip() funktioniert bei Series. Daher konvertierte ich die Datenrahmenspalte in eine Reihe, löschte den Leerraum und ersetzte die konvertierte Spalte wieder in den Datenrahmen. Unten ist der Beispielcode.

import pandas as pd 
data = pd.DataFrame({'values': [' ABC ', ' DEF', ' GHI ']}) 
print ('-----') 
print (data) 

data['values'].str.strip() 
print ('-----') 
print (data) 

new = pd.Series([]) 
new = data['values'].str.strip() 
data['values'] = new 
print ('-----') 
print (new) 
0

Hier ist eine spaltenweise Lösung mit Pandas gelten:

import numpy as np 

def strip_obj(col): 
    if col.dtypes == object: 
     return (col.astype(str) 
        .str.strip() 
        .replace({'nan': np.nan})) 
    return col 

df = df.apply(strip_obj, axis=0) 

Diese Werte in Objekttyp Spalten in String konvertieren. Vorsicht bei Mischsäulen. Zum Beispiel, wenn Ihre Spalte Postleitzahlen mit 20001 und '21110' ist, werden Sie mit '20001' und '21110' enden.

8

Stolperte über diese Frage, während ich nach einem schnellen und minimalistischen Schnipsel suchte, den ich verwenden könnte. Musste mich aus den obigen Posts zusammenstellen. Vielleicht findet jemand es nützlich:

Verwandte Themen