Créer une trame de données pandas remplie de zéro

103

Quelle est la meilleure façon de créer une trame de données pandas remplie de zéro d'une taille donnée?

J'ai utilisé:

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

Y a-t-il une meilleure façon de le faire?

Niedakh
la source
1
Non, je ne vois aucune amélioration substantielle à ce sujet.
Dan Allan
J'obtiens une erreur de mémoire sur np.zeros, car les données sont un grand ensemble. Des conseils sur ce que je peux faire? Je n'ai pas d'autre sortie que "MemoryError". J'ai 100 Go de RAM et les données ne font que 20 Go mais échouent toujours. Aucune idée de comment le déboguer, serveur ubuntu 64 bits. J'ai cherché un peu sur Google, mais tout le monde dit: divisez en morceaux, mais ces données ne peuvent pas être divisées.
niedakh
Pouvez-vous simplement travailler avec data? Pourquoi avez-vous besoin de créer une autre structure pour la tenir?
Phillip Cloud

Réponses:

137

Vous pouvez essayer ceci:

d = pd.DataFrame(0, index=np.arange(len(data)), columns=feature_list)
Shravan
la source
2
Je trouve que tester cela %timeit temp = np.zeros((10, 11)); d = pd.DataFrame(temp, columns = ['col1', 'col2',...'col11'])prend 156 nous. Mais %timeit d = pd.DataFrame(0, index = np.arange(10), columns = ['col1', 'col2',...'col11'])prend 171 nous. Je suis surpris que ce ne soit pas plus rapide.
emschorsch
3
Notez que vous pouvez rencontrer un problème int / float si vous voulez faire quelque chose comme d.set_value(params)après l'initialisation dpour contenir des 0. Une solution facile est: d = pd.DataFrame(0.0, index=np.arange(len(data)), columns=feature_list).
ximiki
29

Il vaut mieux faire ça avec numpy à mon avis

import numpy as np
import pandas as pd
d = pd.DataFrame(np.zeros((N_rows, N_cols)))
AlexG
la source
1
Quand je l'ai fait de cette façon, je ne pouvais pas modifier les valeurs «0». TypeError: 'numpy.float64' object does not support item assignment
RightmireM
@RightmireM Comment essayez-vous exactement de les modifier? Vous avez raison, le type de données estnp.float64
AlexG
11

Similaire à @Shravan, mais sans l'utilisation de numpy:

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

Ensuite, vous pouvez en faire ce que vous voulez:

post_instantiation_fcn = lambda x: str(x)
df_ready_for_whatever = df_0.applymap(post_instantiation_fcn)
WaveRider
la source
8

Si vous souhaitez que le nouveau bloc de données ait le même index et les mêmes colonnes qu'un bloc de données existant, vous pouvez simplement multiplier le bloc de données existant par zéro:

df_zeros = df * 0
chakuRak
la source
2
Sachez que vous obtiendrez des NaN au lieu de zéros partout où df contient des NaN.
kadee
1

Si vous disposez déjà d'un dataframe, c'est le moyen le plus rapide:

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

Comparer aux:

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
la source
1

En supposant avoir un modèle DataFrame, que l'on aimerait copier avec des valeurs nulles remplies ici ...

Si vous n'avez pas de NaN dans votre ensemble de données, la multiplication par zéro peut être beaucoup plus rapide:

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

L'amélioration dépend de la taille de DataFrame, mais ne l'a jamais trouvée plus lente.

Et juste pour le plaisir:

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

Mais:

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

ÉDITER!!!

En supposant que vous ayez un cadre utilisant float64, ce sera le plus rapide de loin! Il est également capable de générer n'importe quelle valeur en remplaçant 0,0 par le nombre de remplissage souhaité.

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

Selon le goût, on peut définir extérieurement nan, et faire une solution générale, quel que soit le type de flotteur particulier:

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
la source
1
C'est certainement la réponse la plus complète sur le timing, bien que pour l'OP, il semble que les besoins en mémoire soient le problème et non la vitesse ... D'ailleurs, sur mon système, les deux premières suggestions que vous avez écrites donnent le même timing (Pandas 0.20.3 ), alors peut-être y a-t-il eu des changements.
Moot