Creación de un marco de datos de pandas relleno de cero

103

¿Cuál es la mejor manera de crear un marco de datos de pandas lleno de ceros de un tamaño determinado?

He usado:

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

Hay una mejor manera de hacerlo?

niedakh
fuente
1
No, no puedo pensar en ninguna mejora sustancial al respecto.
Dan Allan
Recibo un error de memoria en np.zeros, ya que los datos son un gran conjunto. ¿Alguna pista sobre lo que puedo hacer? No tengo otra salida aparte de "MemoryError". Tengo 100 GB de RAM y los datos son solo 20 GB, pero aún fallan. No tengo idea de cómo depurarlo, servidor ubuntu de 64 bits. Busqué en Google un poco, pero todos dicen: divida en trozos, pero estos datos no se pueden dividir.
niedakh
¿Puedes trabajar con data? ¿Por qué necesitas crear otra estructura para sostenerlo?
Phillip Cloud

Respuestas:

138

Puedes probar esto:

d = pd.DataFrame(0, index=np.arange(len(data)), columns=feature_list)
Shravan
fuente
2
Probar esto, encuentro que %timeit temp = np.zeros((10, 11)); d = pd.DataFrame(temp, columns = ['col1', 'col2',...'col11'])nos lleva 156. Pero %timeit d = pd.DataFrame(0, index = np.arange(10), columns = ['col1', 'col2',...'col11'])nos lleva 171. Me sorprende que no sea más rápido.
emschorsch
3
Tenga en cuenta que puede encontrarse con un problema de int / float si va a hacer algo como d.set_value(params)después de inicializar dpara contener ceros. Una solución fácil es: d = pd.DataFrame(0.0, index=np.arange(len(data)), columns=feature_list).
ximiki
29

Es mejor hacer esto con numpy en mi opinión

import numpy as np
import pandas as pd
d = pd.DataFrame(np.zeros((N_rows, N_cols)))
AlexG
fuente
1
Cuando lo hice de esta manera, no pude alterar los valores "0". TypeError: 'numpy.float64' object does not support item assignment
RightmireM
@RightmireM ¿Cómo exactamente estás tratando de modificarlos? Tienes razón, el tipo de datos esnp.float64
AlexG
11

Similar a @Shravan, pero sin el uso de numpy:

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

Entonces puedes hacer lo que quieras con él:

post_instantiation_fcn = lambda x: str(x)
df_ready_for_whatever = df_0.applymap(post_instantiation_fcn)
Montador de olas
fuente
8

Si desea que el nuevo marco de datos tenga el mismo índice y columnas que un marco de datos existente, puede simplemente multiplicar el marco de datos existente por cero:

df_zeros = df * 0
chakuRak
fuente
2
Tenga en cuenta que obtendrá NaN en lugar de ceros siempre que df contenga NaN.
Kadee
1

Si ya tiene un marco de datos, esta es la forma más rápida:

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

Comparar con:

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
fuente
1

Suponiendo que tenga una plantilla DataFrame, que le gustaría copiar con valores cero llenos aquí ...

Si no tiene NaN en su conjunto de datos, multiplicar por cero puede ser significativamente más rápido:

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

La mejora depende del tamaño de DataFrame, pero nunca lo encontré más lento.

Y solo por el gusto de hacerlo:

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

Pero:

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

¡¡¡EDITAR!!!

Suponiendo que tiene un marco que usa float64, ¡este será el más rápido por un gran margen! También puede generar cualquier valor reemplazando 0.0 por el número de llenado deseado.

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

Dependiendo del gusto, uno puede definir externamente nan y hacer una solución general, independientemente del tipo de flotador particular:

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
fuente
1
Esta es definitivamente la respuesta más completa sobre el tiempo, aunque para el OP parece que los requisitos de memoria eran el problema y no la velocidad ... Por cierto, en mi sistema, las dos primeras sugerencias que escribió dan el mismo tiempo (Pandas 0.20.3 ), por lo que tal vez haya habido algunos cambios.
Moot