J'ai une grande quantité de données dans une collection dans mongodb que je dois analyser. Comment importer ces données dans les pandas?
Je suis nouveau aux pandas et aux numpy.
EDIT: La collection mongodb contient des valeurs de capteur étiquetées avec la date et l'heure. Les valeurs des capteurs sont de type flottant.
Exemple de données:
{
"_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
Réponses:
pymongo
pourrait vous donner un coup de main, voici quelques codes que j'utilise:la source
list()
intérieurdf = pd.DataFrame(list(cursor))
s'évalue comme une liste ou un générateur, pour garder le CPU au frais. Si vous avez un million d'items de données et que les quelques lignes suivantes les auraient raisonnablement divisées, au niveau de détail et coupées, le shmegegge entier est toujours en sécurité. Nice.df = pd.DataFrame(list(cursor))
. La requête de base de données pure est beaucoup plus rapide. Pouvons-nous changer lelist
casting pour autre chose?Vous pouvez charger vos données mongodb dans pandas DataFrame en utilisant ce code. Ça marche pour moi. J'espère que vous aussi.
la source
Monary
fait exactement cela, et c'est super rapide . ( un autre lien )Voir ce post sympa qui comprend un tutoriel rapide et quelques horaires.
la source
client = Monary(host, 27017, database="db_tmp") columns = ["col1", "col2"] data_type = ["int64", "int64"] arrays = client.query("db_tmp", "coll", {}, columns, data_type)
pour les50000
enregistrements prend autour200s
.Selon PEP, simple vaut mieux que compliqué:
Vous pouvez inclure des conditions comme vous le feriez avec la base de données mongoDB ordinaire ou même utiliser find_one () pour obtenir un seul élément de la base de données, etc.
et voila!
la source
la source
Pour traiter efficacement les données hors cœur (ne s'intégrant pas dans la RAM) (c'est-à-dire avec une exécution parallèle), vous pouvez essayer l' écosystème Python Blaze : Blaze / Dask / Odo.
Blaze (et Odo ) a des fonctions prêtes à l'emploi pour gérer MongoDB.
Quelques articles utiles pour commencer:
Et un article qui montre ce que des choses incroyables sont possibles avec la pile Blaze: Analyse de 1,7 milliard de commentaires Reddit avec Blaze et Impala (essentiellement, interroger 975 Go de commentaires Reddit en quelques secondes).
PS Je ne suis affilié à aucune de ces technologies.
la source
Une autre option que j'ai trouvée très utile est:
de cette façon, vous obtenez le dépliage des documents imbriqués mongodb gratuitement.
la source
TypeError: data argument can't be an iterator
3.6.7
utilisant des pandas0.24.2
. Peut-être pouvez-vous essayer à ladf = json_normalize(list(cursor))
place?En utilisant
consommera beaucoup de mémoire si le résultat de l'itérateur / générateur est volumineux
mieux vaut générer de petits morceaux et concatter à la fin
la source
http://docs.mongodb.org/manual/reference/mongoexport
exporter vers csv et utiliser
read_csv
ou JSON et utiliserDataFrame.from_records()
la source
DataFrame.from_records()
.Suite à cette excellente réponse en attendantkuo, je voudrais ajouter la possibilité de le faire en utilisant chunksize en ligne avec .read_sql () et .read_csv () . J'élargis la réponse de Deu Leung en évitant d'aller un à un chaque 'enregistrement' de l'itérateur / du 'curseur'. J'emprunterai la fonction read_mongo précédente .
la source
Une approche similaire comme Rafael Valero, waitkuo et Deu Leung utilisant la pagination :
la source
Vous pouvez réaliser ce que vous voulez avec pdmongo en trois lignes:
Si vos données sont très volumineuses, vous pouvez d'abord effectuer une requête agrégée en filtrant les données que vous ne souhaitez pas, puis les mapper aux colonnes souhaitées.
Voici un exemple de mappage
Readings.a
sur colonnea
et de filtrage parreportCount
colonne:read_mongo
accepte les mêmes arguments que l' agrégat pymongola source