wake-up-neo.net

Python/effiziente Methode zum Entfernen von Leerzeichen aus jeder Pandas Data-Frame-Zelle, in der sich ein String-Objekt befindet

Ich lese eine CSV-Datei in einen DataFrame. Ich muss den Whitespace aus allen stringartigen Zellen entfernen und die anderen Zellen in Python 2.7 unverändert lassen.

Folgendes mache ich:

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

my_data = my_data.applymap( remove_whitespace )

Gibt es für Pandas einen besseren oder idiomatischeren Weg, dies zu tun?

Gibt es einen effizienteren Weg (vielleicht durch spaltenweise)?

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

21
deadcode

Auf diese Frage gestoßen, während ich nach einem schnellen und minimalistischen Ausschnitt suchte, den ich verwenden konnte. Musste mich selbst aus Posten oben zusammenbauen. Vielleicht wird es jemand nützlich finden:

data_frame_trimmed = data_frame.apply(lambda x: x.str.strip() if x.dtype == "object" else x)
30
Adam Owczarczyk

Sie können die Series.str.strip()-Methode von pandas verwenden, um dies schnell für jede string-ähnliche Spalte zu tun:

>>> 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
25
jakevdp

Wenn Sie pandas.read_csv aufrufen, können Sie einen regulären Ausdruck verwenden, der mit null oder mehr Leerzeichen gefolgt von einem Komma gefolgt von null oder mehr Leerzeichen als Trennzeichen übereinstimmt.

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 Leerzeichen nach XXX, während die zweite Zeile mit der letzten Y endet.)

Im Folgenden wird pandas.read_csv() zum Lesen der Dateien verwendet, wobei der reguläre Ausdruck ' *, *' als Trennzeichen verwendet wird. (Die Verwendung eines regulären Ausdrucks als Trennzeichen ist nur in der "Python" - Engine von read_csv() verfügbar.)

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
4

Wir wollen:

  1. Wenden Sie unsere Funktion auf jedes Element in unserem Datenrahmen an - verwenden Sie applymap.

  2. Verwenden Sie type(x)==str (versus x.dtype == 'object'), Da Pandas) Spalten als object für Spalten gemischter Datentypen (ein object Spalte kann int und/oder str enthalten).

  3. Behalten Sie den Datentyp jedes Elements bei (wir wollen nicht alles in ein str konvertieren und dann Whitespace entfernen).

Daher habe ich Folgendes als am einfachsten empfunden:

df.applymap(lambda x: x.strip() if type(x)==str else x)

3

Die obige Antwort "data ['values']. Str.strip ()" hat für mich nicht funktioniert, aber ich habe eine einfache Lösung gefunden. Ich bin sicher, dass es einen besseren Weg gibt, dies zu tun. Die Funktion str.strip () funktioniert für Serien. Daher habe ich die Dataframe-Spalte in eine Serie konvertiert, den Leerraum entfernt und die konvertierte Spalte wieder in den Dataframe eingefügt. 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)
3
S. Herron

Ich fand den folgenden Code nützlich und etwas, das wahrscheinlich anderen helfen würde. Mit diesem Snippet können Sie Leerzeichen in einer Spalte sowie im gesamten DataFrame löschen, je nach Anwendungsfall.

import pandas as pd

def remove_whitespace(x):
    try:
        # remove spaces inside and outside of string
        x = "".join(x.split())

    except:
        pass
    return x

# Apply remove_whitespace to column only
df.orderId = df.orderId.apply(remove_whitespace)
print(df)


# Apply to remove_whitespace to entire Dataframe
df = df.applymap(remove_whitespace)
print(df)
0
FunnyChef

Das hat bei mir funktioniert - gilt für den gesamten Datenrahmen:

def panda_strip(x):
    r =[]
    for y in x:
        if isinstance(y, str):
            y = y.strip()

        r.append(y)
    return pd.Series(r)

df = df.apply(lambda x: panda_strip(x))
0
Saul Frank

Hier ist eine spaltenweise Lösung mit Pandas anzuwenden:

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)

Dadurch werden Werte in Objekttypspalten in Zeichenfolge konvertiert. Bei gemischten Säulen ist Vorsicht geboten. Wenn Ihre Spalte beispielsweise Postleitzahlen mit 20001 und '21110' enthält, erhalten Sie '20001' und '21110'. 

0
Blake