মংডোব থেকে পান্ডায় কীভাবে ডেটা আমদানি করবেন?


99

মঙ্গোদবের একটি সংকলনে আমার কাছে প্রচুর পরিমাণে ডেটা রয়েছে যা আমার বিশ্লেষণ করতে হবে। আমি কীভাবে সেই ডেটা পান্ডাতে আমদানি করব?

আমি পান্ডা এবং অদ্ভুত নতুন।

সম্পাদনা: মংডোডব সংগ্রহটিতে তারিখ এবং সময় সহ ট্যাগযুক্ত সেন্সর মান রয়েছে। সেন্সর মানগুলি ভাসমান ডেটাটাইপের হয়।

নমুনা তথ্য:

{
"_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
জথর্পে

উত্তর:


134

pymongo আপনাকে একটি হাত দিতে পারে, অনুসরণগুলি এমন কয়েকটি কোড যা আমি ব্যবহার করছি:

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:%s@%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

ধন্যবাদ, এই পদ্ধতিটি আমি ব্যবহার করে শেষ করেছি। আমার প্রতিটি সারিতে এম্বেড করা নথির একটি অ্যারেও ছিল। সুতরাং আমি পুনরুক্তি করতে হবে পাশাপাশি প্রতিটি সারির মধ্যে। এই কাজ করতে একটি ভাল উপায় আছে কি??
নিতিন

আপনার মঙ্গোদব এর কাঠামোর কয়েকটি নমুনা সরবরাহ করা কি সম্ভব?
ওয়েটিংকুও

4
তালিকা বা জেনারেটর হিসাবে list()অভ্যন্তরের df = pd.DataFrame(list(cursor))মূল্যায়নগুলি সিপিইউকে শীতল রাখার জন্য নোট করুন । আপনার কাছে যদি জিলিয়নেটি এক ডেটা আইটেম থাকে এবং পরবর্তী কয়েকটি লাইনগুলি যুক্তিসঙ্গতভাবে বিভক্ত হয়ে যায়, স্তরীয়-বিশদ হয়ে থাকে এবং সেগুলি কেটে ফেলেছিল তবে পুরো শমেগেজটি এখনও ড্রপ করতে নিরাপদ।
ফিলিপ

4
এটা খুবই ধীর এর @ df = pd.DataFrame(list(cursor))। খাঁটি ডিবি কোয়েরিং অনেক দ্রুত। আমরা কি listঅন্য কিছুতে কাস্টিং পরিবর্তন করতে পারি?
পিটার.কে

4
@ পিটার সেই লাইনটিও আমার চোখে পড়ে। একটি ডাটাবেস কার্সারকে কাস্ট করা, যা পুনরাবৃত্তিযোগ্য হিসাবে নকশাকৃত এবং সম্ভাব্য আকারে প্রচুর পরিমাণে ডেটা মোড়ানো একটি মেমরি তালিকায় আমার কাছে চালাক বলে মনে হয় না।
রাফা

41

আপনি এই কোডটি ব্যবহার করে আপনার মঙ্গোদব ডেটা পানডাস ডেটা ফ্রেমে লোড করতে পারেন। এটা আমার জন্য কাজ করে. আশা করি আপনার জন্যও।

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()))

24

Monaryঠিক এটি করে, এবং এটি সুপার দ্রুত । ( অন্য লিঙ্ক )

একটি দুর্দান্ত টিউটোরিয়াল এবং কিছু সময় অন্তর্ভুক্ত এই দুর্দান্ত পোস্টটি দেখুন ।


Monary স্ট্রিং ডেটা টাইপ সমর্থন করে?
স্নেহাল পরমার

আমি মনারি চেষ্টা করেছিলাম, তবে এটি অনেক সময় নিচ্ছে। আমি কি কিছু অপ্টিমাইজেশন মিস করছি? চেষ্টা করা হয়েছে client = Monary(host, 27017, database="db_tmp") columns = ["col1", "col2"] data_type = ["int64", "int64"] arrays = client.query("db_tmp", "coll", {}, columns, data_type)জন্য 50000রেকর্ড প্রায় লাগে 200s
নিশান্ত

এটি অত্যন্ত ধীর বলে মনে হচ্ছে ... সত্যি বলতে কি, 4 বছর পরে এই প্রকল্পের অবস্থা কী তা আমি জানি না ...
shx2

17

পিইপি অনুসারে জটিল থেকে জটিল সহজ:

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

আপনি নিয়মিত মঙ্গোডিবি ডাটাবেসের সাথে কাজ করতে বা ডেটাবেস থেকে কেবল একটি উপাদান পাওয়ার জন্য ফাইন্ড_োন () ব্যবহার করার কারণে আপনি শর্তাদি অন্তর্ভুক্ত করতে পারেন etc.

ও ভয়েলা!


pd.DataFrame.from_records ডেটাফ্রেম (তালিকা ()) এর মতো ধীর বলে মনে হচ্ছে, তবে ফলাফলগুলি অত্যন্ত বেমানান। %% সময়টি 800 এমএস থেকে শুরু করে 1.9 গুলি
এএফডি

4
এটি বিশাল রেকর্ডগুলির পক্ষে ভাল না কারণ এটি মেমরির ত্রুটিটি দেখায় না, ইনস্ট্রড সিস্টেমটিকে খুব বড় ডেটার জন্য হ্যাং করে। পিডি.ডাটা ফ্রেম (তালিকা (কার্সার)) মেমরি ত্রুটি দেখায়।
অমুল্য আচার্য্য

13
import pandas as pd
from odo import odo

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

9

আউট-অফ-কোর (র্যামের সাথে মানানসই নয়) দক্ষতার সাথে ডেটা ব্যবহার করার জন্য (অর্থাত্ সমান্তরাল সম্পাদনের সাথে), আপনি পাইথন ব্লেজ ইকোসিস্টেমটি চেষ্টা করতে পারেন : ব্লেজ / ডাস্ক / ওডো।

ব্লেজ (এবং ওডো ) -র মঙ্গোডিবি -র সাথে ডিল করার জন্য অফ-অফ-বক্স ফাংশন রয়েছে।

শুরু করার জন্য কয়েকটি দরকারী নিবন্ধ:

এবং একটি নিবন্ধ যা দেখায় যে ব্লেজ স্ট্যাকের মাধ্যমে কী আশ্চর্যজনক জিনিসগুলি সম্ভব: ব্লেজ এবং ইমপালার সাথে 1.7 বিলিয়ন রেডডিট মন্তব্য বিশ্লেষণ করে (মূলত, সেকেন্ডে 975 গিগাবাইট রেডডিট মন্তব্য জিজ্ঞাসা করা হয়)।

পিএস আমি এই প্রযুক্তির কোনওটির সাথেই অনুমোদিত নই।


4
আমি জুপিটার নোটবুক ব্যবহার করে একটি পোস্টও লিখেছি যার উদাহরণটি কীভাবে ডেস্ক এমনকি একটি একক মেশিনে একাধিক কোর ব্যবহার করে মেমরির সাথে মানানসই একটি ডেটা ফিট করার ক্ষেত্রেও দ্রুত গতিতে কার্যকর করতে সহায়তা করে।
ডেনিস গোলোমাজভ

8

আমি খুব দরকারী যে অন্য একটি বিকল্পটি হ'ল:

from pandas.io.json import json_normalize

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

এইভাবে আপনি নিখরচায় মংডোডব নথিগুলি মুক্ত করতে পারেন।


4
এই পদ্ধতির সাথে আমি একটি ত্রুটি পেয়েছিTypeError: data argument can't be an iterator
গ্যাব্রিয়েল ফেয়ার

4
আশ্চর্যের বিষয়, এটি 3.6.7পান্ডাস ব্যবহার করে আমার অজগরটিতে কাজ করে 0.24.2df = json_normalize(list(cursor))পরিবর্তে আপনি চেষ্টা করতে পারেন ?
ইকার পোহোরস্কে

+1 এর জন্য। ডক্স, ম্যাক্স_লেভেল আর্গুমেন্ট ডিকের গভীরতার সর্বোচ্চ স্তরকে সংজ্ঞায়িত করে। আমি সবেমাত্র একটি পরীক্ষা করেছি এবং এটি সত্য নয়, তাই কিছু কলামগুলি বিভক্ত করা দরকার str তবুও, মংডোবের সাথে কাজ করার জন্য খুব সুন্দর বৈশিষ্ট্য।
মরিসিও মারোটো

5

ব্যবহার

pandas.DataFrame(list(...))

যদি পুনরুক্তি / জেনারেটরের ফলাফল বড় হয় তবে প্রচুর স্মৃতি গ্রহণ করবে

শেষে ছোট ছোট খণ্ড এবং কনক্ট তৈরি করা ভাল

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)


1

ওয়েটিংকুওর এই দুর্দান্ত উত্তরের অনুসরণ করে আমি .read_sql () এবং .read_csv () এর সাথে সামঞ্জস্য রেখে চুনসাইজ ব্যবহার করে এমনটি করার সম্ভাবনা যুক্ত করতে চাই । আমি 'পুনরায়' / 'কার্সর' এর প্রতিটি 'রেকর্ড' এড়িয়ে এড়িয়ে ডিউ লেউংয়ের কাছ থেকে উত্তরটি বড় করি । আমি পূর্ববর্তী রিড_মঙ্গো ফাংশন ধার করব ।

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

রাফায়েল Valero, waitingkuo এবং Deu Leung মত অনুরূপ একটি পদ্ধতির ব্যবহার পত্রাঙ্কন :

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

0

আপনি পিডিএমঙ্গো দিয়ে যা চান তা তিন লাইনে অর্জন করতে পারেন :

import pdmongo as pdm
import pandas as pd
df = pdm.read_mongo("MyCollection", [], "mongodb://localhost:27017/mydb")

যদি আপনার ডেটা খুব বড় হয় তবে আপনি চান না এমন ডেটা ফিল্টার করে আপনি প্রথমে একটি সামগ্রিক ক্যোয়ারী করতে পারেন, তারপরে এগুলি আপনার পছন্দসই কলামগুলিতে ম্যাপ করুন।

এখানে Readings.aকলামে ম্যাপিং এবং কলাম aদ্বারা ফিল্টারিংয়ের একটি উদাহরণ রয়েছে reportCount:

import pdmongo as pdm
import pandas as pd
df = pdm.read_mongo("MyCollection", [{'$match': {'reportCount': {'$gt': 6}}}, {'$unwind': '$Readings'}, {'$project': {'a': '$Readings.a'}}], "mongodb://localhost:27017/mydb")

read_mongoপাইমঙ্গো সমষ্টি হিসাবে একই যুক্তি গ্রহণ করে

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.