Der richtige Weg ™, um einen DataFrame zu erstellen
TLDR; (Lies einfach den fetten Text)
Die meisten Antworten hier zeigen Ihnen, wie Sie einen leeren DataFrame erstellen und ausfüllen, aber niemand wird Ihnen sagen, dass dies eine schlechte Sache ist.
Hier ist mein Rat: Warten Sie, bis Sie sicher sind, dass Sie alle Daten haben, mit denen Sie arbeiten müssen. Verwenden Sie eine Liste, um Ihre Daten zu sammeln, und initialisieren Sie dann einen DataFrame, wenn Sie bereit sind.
data = []
for a, b, c in some_function_that_yields_data():
data.append([a, b, c])
df = pd.DataFrame(data, columns=['A', 'B', 'C'])
Es ist immer billiger, an eine Liste anzuhängen und einen DataFrame auf einmal zu erstellen, als einen leeren DataFrame (oder einen von NaNs) zu erstellen und immer wieder daran anzuhängen. Listen beanspruchen außerdem weniger Speicher und sind eine viel leichtere Datenstruktur , anhängen und entfernen können (falls erforderlich).
Der andere Vorteil dieser Methode ist, dass dtypes
automatisch abgeleitet wird (anstatt zuzuweisenobject
allen zuzuweisen).
Der letzte Vorteil ist das a RangeIndex
automatisch für Ihre Daten erstellt wird , sodass Sie sich weniger Sorgen machen müssen (werfen Sie einen Blick auf die Armen append
und loc
Methoden unten, Sie werden in beiden Elementen sehen, die eine angemessene Behandlung des Index erfordern).
Dinge, die Sie NICHT tun sollten
append
oder concat
innerhalb einer Schleife
Hier ist der größte Fehler, den ich von Anfängern gesehen habe:
df = pd.DataFrame(columns=['A', 'B', 'C'])
for a, b, c in some_function_that_yields_data():
df = df.append({'A': i, 'B': b, 'C': c}, ignore_index=True) # yuck
# or similarly,
# df = pd.concat([df, pd.Series({'A': i, 'B': b, 'C': c})], ignore_index=True)
Der Speicher wird für jede append
oder jede concat
Operation neu zugewiesen . Wenn Sie dies mit einer Schleife verbinden, erhalten Sie eine quadratische Komplexitätsoperation . Von demdf.append
Dokumentseite :
Das iterative Anhängen von Zeilen an einen DataFrame kann rechenintensiver sein als eine einzelne Verkettung. Eine bessere Lösung besteht darin, diese Zeilen an eine Liste anzuhängen und die Liste dann gleichzeitig mit dem ursprünglichen DataFrame zu verketten.
Der andere Fehler, der damit verbunden df.append
ist, besteht darin, dass Benutzer häufig vergessen, dass das Anhängen keine In-Place-Funktion ist. Daher muss das Ergebnis zurück zugewiesen werden. Sie müssen sich auch um die dtypes kümmern:
df = pd.DataFrame(columns=['A', 'B', 'C'])
df = df.append({'A': 1, 'B': 12.3, 'C': 'xyz'}, ignore_index=True)
df.dtypes
A object # yuck!
B float64
C object
dtype: object
Der Umgang mit Objektspalten ist niemals eine gute Sache, da Pandas Operationen an diesen Spalten nicht vektorisieren können. Sie müssen dies tun, um das Problem zu beheben:
df.infer_objects().dtypes
A int64
B float64
C object
dtype: object
loc
innerhalb einer Schleife
Ich habe auch gesehen loc
, wie an einen DataFrame angehängt wurde, der leer erstellt wurde:
df = pd.DataFrame(columns=['A', 'B', 'C'])
for a, b, c in some_function_that_yields_data():
df.loc[len(df)] = [a, b, c]
Nach wie vor haben Sie nicht jedes Mal die benötigte Speichermenge vorab zugewiesen, sodass der Speicher jedes Mal neu vergrößert wird, wenn Sie eine neue Zeile erstellen . Es ist genauso schlimm wieappend
und noch hässlicher.
Leerer Datenrahmen von NaNs
Und dann wird ein DataFrame mit NaNs und allen damit verbundenen Einschränkungen erstellt.
df = pd.DataFrame(columns=['A', 'B', 'C'], index=range(5))
df
A B C
0 NaN NaN NaN
1 NaN NaN NaN
2 NaN NaN NaN
3 NaN NaN NaN
4 NaN NaN NaN
Es erstellt wie die anderen einen DataFrame aus Objektspalten.
df.dtypes
A object # you DON'T want this
B object
C object
dtype: object
Das Anhängen hat immer noch alle Probleme wie die oben genannten Methoden.
for i, (a, b, c) in enumerate(some_function_that_yields_data()):
df.iloc[i] = [a, b, c]
Der Beweis ist im Pudding
Das Timing dieser Methoden ist der schnellste Weg, um festzustellen, wie stark sie sich in Bezug auf Speicher und Nutzen unterscheiden.
Benchmarking-Code als Referenz.