Wie kann man das Trennzeichen in pandas read_csv flexibler für Leerzeichen für unregelmäßige Trennzeichen machen?

75

Ich muss einen Datenrahmen erstellen, indem ich Daten aus einer Datei mit der read_csvMethode einlese. Die Trennzeichen sind jedoch nicht sehr regelmäßig: Einige Spalten sind durch Tabulatoren ( \t) getrennt, andere durch Leerzeichen. Darüber hinaus können einige Spalten durch 2 oder 3 oder mehr Leerzeichen oder sogar durch eine Kombination von Leerzeichen und Tabulatoren getrennt werden (z. B. 3 Leerzeichen, zwei Tabulatoren und dann 1 Leerzeichen).

Gibt es eine Möglichkeit, Pandas anzuweisen, diese Dateien richtig zu behandeln?

Übrigens habe ich dieses Problem nicht, wenn ich Python verwende. Ich benutze:

for line in file(file_name):
   fld = line.split()

Und es funktioniert perfekt. Es ist egal, ob zwischen den Feldern 2 oder 3 Leerzeichen stehen. Selbst Kombinationen von Leerzeichen und Tabulatoren verursachen keine Probleme. Können Pandas dasselbe tun?

römisch
quelle

Antworten:

129

In der Dokumentation können Sie entweder einen regulären Ausdruck verwenden oder delim_whitespace:

>>> import pandas as pd
>>> for line in open("whitespace.csv"):
...     print repr(line)
...     
'a\t  b\tc 1 2\n'
'd\t  e\tf 3 4\n'
>>> pd.read_csv("whitespace.csv", header=None, delimiter=r"\s+")
   0  1  2  3  4
0  a  b  c  1  2
1  d  e  f  3  4
>>> pd.read_csv("whitespace.csv", header=None, delim_whitespace=True)
   0  1  2  3  4
0  a  b  c  1  2
1  d  e  f  3  4
DSM
quelle
4
Sie können auch verwenden skipinitialspace, um das anfängliche Leerzeichen zu überspringen
jarondl
Wie funktioniert es, wenn ich ein txt.fileund das Format habe, dass ich eine Nummer gefolgt von mindestens zwei Leerzeichen habe? Die Formel delimiter=r"\d\d\s\s+funktioniert nicht
PV8
@ PV8: in diesem Fall ist dein Trennzeichen immer noch nur \s+oder \s{2,}. Fügen Sie \d\ddem Trennzeichen keinen Ausdruck für das Feld hinzu ! Trennzeichen ist nur das Trennzeichen! Feld ist alles zwischen Trennzeichen (oder Anführungszeichen).
smci
Wie greife ich über die Liste auf das einzelne Element zu? Wenn mir das gefällt df = pd.read_csv ("whitespace.csv", header = None, delim_whitespace = True), druckt print (df [0]) nur das erste Element 0, aber es druckt nicht das nächste Element, wenn ich print ( df [1]) ist es nicht eine Liste?
Scharfschütze
13
>>> pd.read_csv("whitespace.csv", header = None, sep = "\s+|\t+|\s+\t+|\t+\s+")

würde eine beliebige Kombination von beliebig vielen Leerzeichen und Tabulatoren als Trennzeichen verwenden.

Friedlich
quelle
3

Pandas hat zwei CSV-Reader und ist nur in Bezug auf redundante führende Leerzeichen flexibel:

pd.read_csv("whitespace.csv", skipinitialspace=True)

während man nicht ist

pd.DataFrame.from_csv("whitespace.csv")

Weder ist Out-of-the-Box flexibel in Bezug auf nachgestellte Leerzeichen, siehe die Antworten mit regulären Ausdrücken. Vermeiden Sie delim_whitespace, da nur Leerzeichen (ohne oder \ t) als Trennzeichen zugelassen werden.

Gerben
quelle
2

Wir können dies in Betracht ziehen, um alle Kombinationen und null oder mehr Vorkommen zu berücksichtigen.

pd.read_csv("whitespace.csv", header = None, sep = "[ \t]*,[ \t]*")
Yoonghm
quelle