Tengo una gran cantidad de datos en una colección en mongodb que necesito analizar. ¿Cómo importo esos datos a pandas?
Soy nuevo en pandas y numpy.
EDITAR: La colección mongodb contiene valores de sensor etiquetados con fecha y hora. Los valores del sensor son del tipo de datos flotantes.
Data de muestra:
{
"_cls" : "SensorReport",
"_id" : ObjectId("515a963b78f6a035d9fa531b"),
"_types" : [
"SensorReport"
],
"Readings" : [
{
"a" : 0.958069536790466,
"_types" : [
"Reading"
],
"ReadingUpdatedDate" : ISODate("2013-04-02T08:26:35.297Z"),
"b" : 6.296118156595,
"_cls" : "Reading"
},
{
"a" : 0.95574014778624,
"_types" : [
"Reading"
],
"ReadingUpdatedDate" : ISODate("2013-04-02T08:27:09.963Z"),
"b" : 6.29651468650064,
"_cls" : "Reading"
},
{
"a" : 0.953648289182713,
"_types" : [
"Reading"
],
"ReadingUpdatedDate" : ISODate("2013-04-02T08:27:37.545Z"),
"b" : 7.29679823731148,
"_cls" : "Reading"
},
{
"a" : 0.955931884300997,
"_types" : [
"Reading"
],
"ReadingUpdatedDate" : ISODate("2013-04-02T08:28:21.369Z"),
"b" : 6.29642922525632,
"_cls" : "Reading"
},
{
"a" : 0.95821381,
"_types" : [
"Reading"
],
"ReadingUpdatedDate" : ISODate("2013-04-02T08:41:20.801Z"),
"b" : 7.28956613,
"_cls" : "Reading"
},
{
"a" : 4.95821335,
"_types" : [
"Reading"
],
"ReadingUpdatedDate" : ISODate("2013-04-02T08:41:36.931Z"),
"b" : 6.28956574,
"_cls" : "Reading"
},
{
"a" : 9.95821341,
"_types" : [
"Reading"
],
"ReadingUpdatedDate" : ISODate("2013-04-02T08:42:09.971Z"),
"b" : 0.28956488,
"_cls" : "Reading"
},
{
"a" : 1.95667927,
"_types" : [
"Reading"
],
"ReadingUpdatedDate" : ISODate("2013-04-02T08:43:55.463Z"),
"b" : 0.29115237,
"_cls" : "Reading"
}
],
"latestReportTime" : ISODate("2013-04-02T08:43:55.463Z"),
"sensorName" : "56847890-0",
"reportCount" : 8
}
mongo_doc.data_frame = my_pandas_df
Respuestas:
pymongo
podría echarte una mano, los siguientes son algunos códigos que estoy usando:fuente
list()
en cuenta que el interior sedf = pd.DataFrame(list(cursor))
evalúa como una lista o generador, para mantener fría la CPU. Si tiene un trillón de elementos de datos, y las siguientes líneas los habrían dividido razonablemente, nivel de detalle y recortado, todo el shmegegge todavía es seguro para caer. Bien.df = pd.DataFrame(list(cursor))
. La búsqueda pura de db es mucho más rápida. ¿Podríamos cambiar ellist
casting a otra cosa?Puede cargar sus datos de mongodb en pandas DataFrame usando este código. Esto funciona para mi. Ojalá para ti también.
fuente
Monary
hace exactamente eso, y es súper rápido . ( otro enlace )Vea esta interesante publicación que incluye un tutorial rápido y algunos horarios.
fuente
client = Monary(host, 27017, database="db_tmp") columns = ["col1", "col2"] data_type = ["int64", "int64"] arrays = client.query("db_tmp", "coll", {}, columns, data_type)
para50000
registros lleva alrededor200s
.Según PEP, lo simple es mejor que complicado:
Puede incluir condiciones como lo haría trabajando con una base de datos mongoDB normal o incluso usar find_one () para obtener solo un elemento de la base de datos, etc.
¡y voilá!
fuente
fuente
Para tratar con datos fuera del núcleo (que no encajan en la RAM) de manera eficiente (es decir, con ejecución paralela), puede probar el ecosistema Python Blaze : Blaze / Dask / Odo.
Blaze (y Odo ) tiene funciones listas para usar para lidiar con MongoDB.
Algunos artículos útiles para comenzar:
Y un artículo que muestra qué cosas asombrosas son posibles con la pila Blaze: Analizando 1.7 mil millones de comentarios de Reddit con Blaze e Impala (esencialmente, consultando 975 Gb de comentarios de Reddit en segundos).
PD: No estoy afiliado a ninguna de estas tecnologías.
fuente
Otra opción que encontré muy útil es:
de esta manera, obtiene el despliegue de documentos mongodb anidados de forma gratuita.
fuente
TypeError: data argument can't be an iterator
3.6.7
usando pandas0.24.2
. ¿Quizás puedas intentarlo en sudf = json_normalize(list(cursor))
lugar?Utilizando
consumirá mucha memoria si el resultado del iterador / generador es grande
mejor generar pequeños trozos y concat al final
fuente
http://docs.mongodb.org/manual/reference/mongoexport
exportar a csv y usar
read_csv
o JSON y usarDataFrame.from_records()
fuente
DataFrame.from_records()
.Siguiendo esta gran respuesta esperandokuo, me gustaría agregar la posibilidad de hacerlo usando chunksize en línea con .read_sql () y .read_csv () . Amplío la respuesta de Deu Leung evitando ir uno por uno a cada 'registro' del 'iterador' / 'cursor'. Tomaré prestada la función read_mongo anterior .
fuente
Un enfoque similar como Rafael Valero, waitkuo y Deu Leung usando paginación :
fuente
Puedes lograr lo que quieras con pdmongo en tres líneas:
Si sus datos son muy grandes, puede hacer una consulta agregada primero filtrando los datos que no desea y luego mapeándolos a las columnas deseadas.
A continuación, se muestra un ejemplo de asignación
Readings.a
a columnaa
y filtrado porreportCount
columna:read_mongo
acepta los mismos argumentos que el agregado de pymongofuente