it-swarm.com.de

Wie importiere ich Daten von Mongodb zu Pandas?

Ich habe eine große Datenmenge in einer Sammlung in Mongodb, die ich analysieren muss. Wie importiere ich diese Daten zu Pandas?

Ich bin neu in pandas und numpy.

BEARBEITEN: Die Mongodb-Sammlung enthält Sensorwerte mit Datum und Uhrzeit. Die Sensorwerte sind vom Datentyp float.

Beispieldaten:

{
"_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
}
78
Nithin

pymongo könnte Ihnen helfen, die folgenden Codes verwende ich:

import pandas as pd
from pymongo import MongoClient


def _connect_mongo(Host, port, username, password, db):
    """ A util for making a connection to mongo """

    if username and password:
        mongo_uri = 'mongodb://%s:%[email protected]%s:%s/%s' % (username, password, Host, port, db)
        conn = MongoClient(mongo_uri)
    else:
        conn = MongoClient(Host, port)


    return conn[db]


def read_mongo(db, collection, query={}, Host='localhost', port=27017, username=None, password=None, no_id=True):
    """ Read from Mongo and Store into DataFrame """

    # Connect to MongoDB
    db = _connect_mongo(Host=host, port=port, username=username, password=password, db=db)

    # Make a query to the specific DB and Collection
    cursor = db[collection].find(query)

    # Expand the cursor and construct the DataFrame
    df =  pd.DataFrame(list(cursor))

    # Delete the _id
    if no_id:
        del df['_id']

    return df
104
waitingkuo

Sie können Ihre Mongodb-Daten mit diesem Code in pandas DataFrame laden. Es funktioniert für mich. Hoffentlich auch für Sie.

import pymongo
import pandas as pd
from pymongo import MongoClient
client = MongoClient()
db = client.database_name
collection = db.collection_name
data = pd.DataFrame(list(collection.find()))
30

Monary macht genau das und es ist superschnell . ( anderer Link )

Siehe dieser coole Beitrag , der ein kurzes Tutorial und einige Timings enthält.

22
shx2

Nach PEP ist einfach besser als kompliziert:

import pandas as pd
df = pd.DataFrame.from_records(db.<database_name>.<collection_name>.find())

Sie können Bedingungen wie bei einer normalen MongoDB-Datenbank einfügen oder sogar find_one () verwenden, um nur ein Element aus der Datenbank abzurufen.

und voila!

11
Cy Bu
import pandas as pd
from odo import odo

data = odo('mongodb://localhost/db::collection', pd.DataFrame)
10
fengwt

Um mit Daten außerhalb des Kerns (die nicht in den RAM passen) effizient umzugehen (d. H. Bei paralleler Ausführung), können Sie Folgendes versuchen: Python Blaze-Ökosystem : Blaze/Dask/Odo.

Blaze (und Odo ) haben sofort einsatzbereite Funktionen für MongoDB.

Ein paar nützliche Artikel zum Einstieg:

Und ein Artikel, der zeigt, welche erstaunlichen Dinge mit Blaze Stack möglich sind: Analyse von 1,7 Milliarden Reddit-Kommentaren mit Blaze und Impala (Abfrage von 975 GB Reddit-Kommentaren in Sekunden).

P.S. Ich bin mit keiner dieser Technologien verbunden.

6

Eine andere Option, die ich sehr nützlich fand, ist:

from pandas.io.json import json_normalize

cursor = my_collection.find()
df = json_normalize(cursor)

auf diese Weise erhalten Sie die Entfaltung von verschachtelten Mongodb-Dokumenten kostenlos.

4
Ikar Pohorský

Verwenden

pandas.DataFrame(list(...))

verbraucht viel Speicher, wenn das Ergebnis des Iterators/Generators groß ist

am ende lieber kleine brocken und concat erzeugen

def iterator2dataframes(iterator, chunk_size: int):
  """Turn an iterator into multiple small pandas.DataFrame

  This is a balance between memory and efficiency
  """
  records = []
  frames = []
  for i, record in enumerate(iterator):
    records.append(record)
    if i % chunk_size == chunk_size - 1:
      frames.append(pd.DataFrame(records))
      records = []
  if records:
    frames.append(pd.DataFrame(records))
  return pd.concat(frames)
3
Deo Leung

http://docs.mongodb.org/manual/reference/mongoexport

exportiere nach csv und benutze read_csv oder JSON und benutze DataFrame.from_records

2
Jeff

Nach dieser tollen Antwort von waitingkuo möchte ich die Möglichkeit hinzufügen, dies mit chunksize in Übereinstimmung mit . Read_sql () und . Read_csv () zu tun =. Ich erweitere die Antwort von Deu Leung , indem ich vermeide, jeden 'Datensatz' des 'Iterators'/'Cursors' einzeln aufzurufen. Ich werde vorherige read_mongo Funktion ausleihen.

def read_mongo(db, 
           collection, query={}, 
           Host='localhost', port=27017, 
           username=None, password=None,
           chunksize = 100, no_id=True):
""" Read from Mongo and Store into DataFrame """


# Connect to MongoDB
#db = _connect_mongo(Host=host, port=port, username=username, password=password, db=db)
client = MongoClient(Host=host, port=port)
# Make a query to the specific DB and Collection
db_aux = client[db]


# Some variables to create the chunks
skips_variable = range(0, db_aux[collection].find(query).count(), int(chunksize))
if len(skips_variable)<=1:
    skips_variable = [0,len(skips_variable)]

# Iteration to create the dataframe in chunks.
for i in range(1,len(skips_variable)):

    # Expand the cursor and construct the DataFrame
    #df_aux =pd.DataFrame(list(cursor_aux[skips_variable[i-1]:skips_variable[i]]))
    df_aux =pd.DataFrame(list(db_aux[collection].find(query)[skips_variable[i-1]:skips_variable[i]]))

    if no_id:
        del df_aux['_id']

    # Concatenate the chunks into a unique df
    if 'df' not in locals():
        df =  df_aux
    else:
        df = pd.concat([df, df_aux], ignore_index=True)

return df
1
Rafael Valero

Ein ähnlicher Ansatz wie Rafael Valero, waitingkuo und Deu Leung mit Paginierung:

def read_mongo(
       # db, 
       collection, query=None, 
       # Host='localhost', port=27017, username=None, password=None,
       chunksize = 100, page_num=1, no_id=True):

    # Connect to MongoDB
    db = _connect_mongo(Host=host, port=port, username=username, password=password, db=db)

    # Calculate number of documents to skip
    skips = chunksize * (page_num - 1)

    # Sorry, this is in spanish
    # https://www.toptal.com/python/c%C3%B3digo-buggy-python-los-10-errores-m%C3%A1s-comunes-que-cometen-los-desarrolladores-python/es
    if not query:
        query = {}

    # Make a query to the specific DB and Collection
    cursor = db[collection].find(query).skip(skips).limit(chunksize)

    # Expand the cursor and construct the DataFrame
    df =  pd.DataFrame(list(cursor))

    # Delete the _id
    if no_id:
        del df['_id']

    return df
1
Jordy Cuan