Cómo almacenar un dataframe usando Pandas
Ahora mismo estoy importando un CSV
bastante grande como un dataframe cada vez que corro el script. ¿Hay una buena solución para mantener ese dataframe constantemente disponible entre ejecuciones para que no tenga que pasar todo ese tiempo esperando que se ejecute el script?
8 answers
La forma más fácil es a pickle usando to_pickle
:
df.to_pickle(file_name) # where to save it, usually as a .pkl
Luego puede cargarlo de nuevo usando:
df = pd.read_pickle(file_name)
Nota: antes de 0.11.1 save
y load
eran la única manera de hacer esto (ahora están en desuso a favor de to_pickle
y read_pickle
respectivamente).
Otra opción popular es utilizar HDF5 (pytables ) que ofrece tiempos de acceso muy rápidos para conjuntos de datos grandes:
store = HDFStore('store.h5')
store['df'] = df # save it
store['df'] # load it
Más avanzado las estrategias se discuten en ellibro de cocina .
Desde 0.13 también hay msgpack que puede ser mejor para la interoperabilidad, como una alternativa más rápida a JSON, o si tiene datos de objetos/texto pesados de python (consulte esta pregunta).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:54:50
Aunque ya hay algunas respuestas, encontré una buena comparación en la que intentaron varias formas de serializar los DataFrames de Pandas: Almacene eficientemente los DataFrames de Pandas.
Comparan:
- pepinillo: formato de datos ASCII original
- cPickle, una biblioteca en C
- pickle-p2: utiliza el nuevo formato binario
- json: biblioteca json de standardlib
- json-no-index: como json, pero sin índice
- msgpack: JSON binario alternativa
- CSV
- hdfstore: formato de almacenamiento HDF5
En su experimento, serializan un DataFrame de 1,000,000 filas con las dos columnas probadas por separado: una con datos de texto, la otra con números. Su descargo de responsabilidad dice:
No debe confiar en que lo que sigue se generalice a sus datos. Usted debe mirar sus propios datos y ejecutar benchmarks usted mismo
El código fuente para la prueba a la que se refieren está disponible en línea. Dado que este código no funcionaba directamente, hice algunos cambios menores, que puedes obtener aquí: serialize.py Obtuve los siguientes resultados:
También mencionan que con la conversión de datos de texto a datos categóricos la serialización es mucho más rápida. En su prueba alrededor de 10 veces más rápido (también ver el código de prueba).
Edit : Los tiempos más altos para pickle que csv se pueden explicar por el formato de datos utilizado. Por defecto pickle
utiliza una representación ASCII imprimible, que genera conjuntos de datos más grandes. Sin embargo, como se puede ver en el gráfico, pickle usando el nuevo formato de datos binarios (versión 2, pickle-p2
) tiene tiempos de carga mucho más bajos.
Algunas otras referencias:
- En la pregunta Biblioteca de Python más rápida para leer un archivo CSV hay una respuesta muy detallada que compara diferentes bibliotecas para leer archivos csv con un punto de referencia. El resultado es que para leer csv archivos
numpy.fromfile
es el más rápido. - Otra prueba de serialización muestra msgpack-python, ujson , y cPickle para ser el más rápido en serialización.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-21 21:18:36
Si entiendo correctamente, ya está usando pandas.read_csv()
pero le gustaría acelerar el proceso de desarrollo para que no tenga que cargar el archivo cada vez que edite su script, ¿es correcto? Tengo algunas recomendaciones:
-
Puede cargar solo una parte del archivo CSV usando
pandas.read_csv(..., nrows=1000)
para cargar solo el bit superior de la tabla, mientras está haciendo el desarrollo Use ipython para una sesión interactiva, de modo que mantenga la tabla pandas en memoria mientras edita y recarga su script.
Actualizado use
DataFrame.to_feather()
ypd.read_feather()
para almacenar datos en el formato binario compatible con R feather que es súper rápido (en mis manos, ligeramente más rápido quepandas.to_pickle()
en datos numéricos y mucho más rápido en datos de cadenas).
También te puede interesar esta respuesta en stackoverflow.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-30 17:43:18
El pepinillo funciona bien!
import pandas as pd
df.to_pickle('123.pkl') #to save the dataframe, df to 123.pkl
df1 = pd.read_pickle('123.pkl') #to load 123.pkl back to the dataframe df
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-01 10:44:45
Los DataFrames Pandas tienen la función to_pickle
que es útil para guardar un DataFrame:
import pandas as pd
a = pd.DataFrame({'A':[0,1,0,1,0],'B':[True, True, False, False, False]})
print a
# A B
# 0 0 True
# 1 1 True
# 2 0 False
# 3 1 False
# 4 0 False
a.to_pickle('my_file.pkl')
b = pd.read_pickle('my_file.pkl')
print b
# A B
# 0 0 True
# 1 1 True
# 2 0 False
# 3 1 False
# 4 0 False
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-12 21:46:29
Puede utilizar el archivo de formato de pluma. Es extremadamente rápido.
df.to_feather('filename.ft')
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-17 06:28:51
Los formatos de archivo Numpy son bastante rápidos para datos numéricos
Prefiero usar archivos numpy ya que son rápidos y fáciles de trabajar. Aquí hay un punto de referencia simple para guardar y cargar un dataframe con 1 columna de 1 millón de puntos.
import numpy as np
import pandas as pd
num_dict = {'voltage': np.random.rand(1000000)}
num_df = pd.DataFrame(num_dict)
Usando la función mágica de ipython %%timeit
%%timeit
with open('num.npy', 'wb') as np_file:
np.save(np_file, num_df)
La salida es
100 loops, best of 3: 5.97 ms per loop
Para cargar los datos de nuevo en un dataframe
%%timeit
with open('num.npy', 'rb') as np_file:
data = np.load(np_file)
data_df = pd.DataFrame(data)
La salida es
100 loops, best of 3: 5.12 ms per loop
NO ESTÁ MAL!
CONS
Hay un problema si guardas el archivo numpy usando python 2 y luego intente abrirlo usando python 3 (o viceversa).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-13 18:31:42
import pickle
example_dict = {1:"6",2:"2",3:"g"}
pickle_out = open("dict.pickle","wb")
pickle.dump(example_dict, pickle_out)
pickle_out.close()
El código anterior guardará el archivo pickle
pickle_in = open("dict.pickle","rb")
example_dict = pickle.load(pickle_in)
Estas dos líneas abrirán el archivo de pepinillos guardado
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-16 17:20:21