Erstellen eines mit Nullen gefüllten Pandas-Datenrahmens

100

Was ist der beste Weg, um einen mit Nullen gefüllten Pandas-Datenrahmen einer bestimmten Größe zu erstellen?

Ich habe benutzt:

zero_data = np.zeros(shape=(len(data),len(feature_list)))
d = pd.DataFrame(zero_data, columns=feature_list)

Gibt es einen besseren Weg, dies zu tun?

Niedakh
quelle
1
Nein, ich kann mir keine wesentliche Verbesserung vorstellen.
Dan Allan
Ich erhalte einen Speicherfehler auf np.zeros, da die Daten eine große Menge sind. Irgendwelche Hinweise, was ich tun kann? Ich habe außer "MemoryError" keine andere Ausgabe erhalten. Ich habe 100 GB RAM und die Daten sind nur 20 GB, aber immer noch fehlgeschlagen. Keine Ahnung, wie man es debuggt, 64bit Ubuntu Server. Ich habe ein bisschen gegoogelt, aber jeder sagt - in Stücke teilen, aber diese Daten können nicht geteilt werden.
Niedakh
Kannst du einfach damit arbeiten data? Warum müssen Sie eine andere Struktur erstellen, um sie zu halten?
Phillip Cloud

Antworten:

132

Sie können dies versuchen:

d = pd.DataFrame(0, index=np.arange(len(data)), columns=feature_list)
Shravan
quelle
2
Um dies zu testen, brauche ich %timeit temp = np.zeros((10, 11)); d = pd.DataFrame(temp, columns = ['col1', 'col2',...'col11'])156. Aber %timeit d = pd.DataFrame(0, index = np.arange(10), columns = ['col1', 'col2',...'col11'])nimmt uns 171. Ich bin überrascht, dass es nicht schneller geht.
Emschorsch
3
Beachten Sie, dass möglicherweise ein Problem mit int / float auftritt, wenn Sie d.set_value(params)nach der Initialisierung so etwas wie Nullen ausführen d. Eine einfache Lösung ist : d = pd.DataFrame(0.0, index=np.arange(len(data)), columns=feature_list).
Ximiki
29

Meiner Meinung nach ist es am besten, dies mit Numpy zu tun

import numpy as np
import pandas as pd
d = pd.DataFrame(np.zeros((N_rows, N_cols)))
AlexG
quelle
1
Wenn ich es so gemacht habe, konnte ich die "0" -Werte nicht ändern. TypeError: 'numpy.float64' object does not support item assignment
RightmireM
@RightmireM Wie genau versuchst du sie zu ändern? Sie sind richtig, der Datentyp istnp.float64
AlexG
11

Ähnlich wie @Shravan, jedoch ohne Verwendung von numpy:

  height = 10
  width = 20
  df_0 = pd.DataFrame(0, index=range(height), columns=range(width))

Dann können Sie damit machen, was Sie wollen:

post_instantiation_fcn = lambda x: str(x)
df_ready_for_whatever = df_0.applymap(post_instantiation_fcn)
Wellenreiter
quelle
8

Wenn Sie möchten, dass der neue Datenrahmen denselben Index und dieselben Spalten wie ein vorhandener Datenrahmen hat, können Sie den vorhandenen Datenrahmen einfach mit Null multiplizieren:

df_zeros = df * 0
chakuRak
quelle
1
Beachten Sie, dass Sie überall dort NaNs anstelle von Nullen erhalten, wo df NaNs enthält.
Kadee
1

Wenn Sie bereits einen Datenrahmen haben, ist dies der schnellste Weg:

In [1]: columns = ["col{}".format(i) for i in range(10)]
In [2]: orig_df = pd.DataFrame(np.ones((10, 10)), columns=columns)
In [3]: %timeit d = pd.DataFrame(np.zeros_like(orig_df), index=orig_df.index, columns=orig_df.columns)
10000 loops, best of 3: 60.2 µs per loop

Vergleichen mit:

In [4]: %timeit d = pd.DataFrame(0, index = np.arange(10), columns=columns)
10000 loops, best of 3: 110 µs per loop

In [5]: temp = np.zeros((10, 10))
In [6]: %timeit d = pd.DataFrame(temp, columns=columns)
10000 loops, best of 3: 95.7 µs per loop
mtd
quelle
1

Angenommen, Sie haben eine Vorlage DataFrame, die Sie mit den hier ausgefüllten Nullwerten kopieren möchten ...

Wenn Ihr Datensatz keine NaNs enthält, kann das Multiplizieren mit Null erheblich schneller sein:

In [19]: columns = ["col{}".format(i) for i in xrange(3000)]                                                                                       

In [20]: indices = xrange(2000)

In [21]: orig_df = pd.DataFrame(42.0, index=indices, columns=columns)

In [22]: %timeit d = pd.DataFrame(np.zeros_like(orig_df), index=orig_df.index, columns=orig_df.columns)
100 loops, best of 3: 12.6 ms per loop

In [23]: %timeit d = orig_df * 0.0
100 loops, best of 3: 7.17 ms per loop

Die Verbesserung hängt von der Größe des DataFrames ab, wurde jedoch nie langsamer.

Und nur zum Teufel:

In [24]: %timeit d = orig_df * 0.0 + 1.0
100 loops, best of 3: 13.6 ms per loop

In [25]: %timeit d = pd.eval('orig_df * 0.0 + 1.0')
100 loops, best of 3: 8.36 ms per loop

Aber:

In [24]: %timeit d = orig_df.copy()
10 loops, best of 3: 24 ms per loop

BEARBEITEN!!!

Angenommen, Sie haben einen Frame mit float64, dann ist dies mit großem Abstand der schnellste! Es kann auch einen beliebigen Wert generieren, indem 0.0 durch die gewünschte Füllnummer ersetzt wird.

In [23]: %timeit d = pd.eval('orig_df > 1.7976931348623157e+308 + 0.0')
100 loops, best of 3: 3.68 ms per loop

Je nach Geschmack kann man nan extern definieren und eine allgemeine Lösung finden, unabhängig vom jeweiligen Schwimmertyp:

In [39]: nan = np.nan
In [40]: %timeit d = pd.eval('orig_df > nan + 0.0')
100 loops, best of 3: 4.39 ms per loop
Mark Horvath
quelle
1
Dies ist definitiv die umfassendste Antwort zum Timing, obwohl es für das OP so aussieht, als ob der Speicherbedarf das Problem und nicht die Geschwindigkeit war ... Übrigens geben auf meinem System die ersten beiden Vorschläge, die Sie geschrieben haben, das gleiche Timing (Pandas 0.20.3) ), also gab es vielleicht einige Änderungen.
Moot