python - يتدفق العمل "بيانات كبيرة" باستخدام الباندا




mongodb pandas (9)

لقد حاولت حل لغز الإجابة على هذا السؤال لعدة أشهر أثناء تعلم الباندا. أستخدم SAS في العمل اليومي الخاص بي وهو أمر رائع لدعمه غير الأساسي. ومع ذلك ، SAS مروعة مثل قطعة من البرمجيات لعدة أسباب أخرى.

في يوم من الأيام ، آمل أن أحل محل استخدام SAS مع python و pandas ، لكني أفتقر حالياً إلى تدفق عمل خارج عن العمل لمجموعات البيانات الكبيرة. أنا لا أتحدث عن "البيانات الضخمة" التي تتطلب شبكة موزعة ، ولكنها بالأحرى ملفات كبيرة جدًا لا تتناسب مع الذاكرة ولكنها صغيرة بما يكفي لتناسب محرك الأقراص الثابتة.

فكرتي الأولى هي استخدام HDFStore لعقد مجموعات كبيرة من البيانات على القرص وسحب القطع التي أحتاجها فقط في مخططات البيانات لتحليلها. ذكر آخرون أن MongoDB أسهل في استخدام البديل. سؤالي هو:

ما هي بعض مهام سير العمل الأفضل لإنجاز ما يلي:

  1. تحميل الملفات المسطحة إلى بنية قاعدة بيانات دائمة على القرص
  2. الاستعلام عن قاعدة البيانات هذه لاسترجاع البيانات لإدخالها في بنية بيانات الباندا
  3. تحديث قاعدة البيانات بعد معالجة القطع في الباندا

ستكون الأمثلة في العالم الحقيقي موضع تقدير كبير ، خاصة من أي شخص يستخدم الباندا على "بيانات كبيرة".

تحرير - مثال عن كيف أود أن يعمل هذا:

  1. يتم بشكل متكرر استيراد ملف مسطح كبير وتخزينه في بنية قاعدة بيانات ثابتة على القرص. هذه الملفات عادةً كبيرة جدًا لتناسب الذاكرة.
  2. من أجل استخدام Pandas ، أود قراءة مجموعات فرعية من هذه البيانات (عادةً عدد قليل من الأعمدة في كل مرة) يمكن وضعها في الذاكرة.
  3. أود إنشاء أعمدة جديدة عن طريق تنفيذ عمليات مختلفة على الأعمدة المحددة.
  4. عندئذ يجب إلحاق هذه الأعمدة الجديدة في بنية قاعدة البيانات.

أحاول العثور على أفضل طريقة لإجراء هذه الخطوات. قراءة الروابط حول الباندا و pytables يبدو أن إلحاق عمود جديد قد يكون مشكلة.

تعديل - الرد على أسئلة جيف على وجه التحديد:

  1. أقوم ببناء نماذج مخاطر الائتمان الاستهلاكي. تشمل أنواع البيانات الهاتف و SSN وخصائص العنوان ؛ قيم العقارات معلومات مهينة مثل السجلات الجنائية ، والإفلاس ، إلخ ... تحتوي مجموعات البيانات التي أستخدمها يوميًا على ما يقرب من 1000 إلى 2000 حقل في المتوسط ​​لأنواع البيانات المختلطة: المتغيرات المستمرة ، الاسمية والترتيبية لكل من البيانات الرقمية والحروف. نادراً ما أقوم بإلحاق صفوف ، لكنني أقوم بالعديد من العمليات التي تقوم بإنشاء أعمدة جديدة.
  2. تتضمن العمليات النموذجية دمج عدة أعمدة باستخدام منطق شرطي في عمود مركب جديد. على سبيل المثال ، if var1 > 2 then newvar = 'A' elif var2 = 4 then newvar = 'B' . نتيجة هذه العمليات عبارة عن عمود جديد لكل سجل في مجموعة البيانات الخاصة بي.
  3. وأخيرًا ، أود إلحاق هذه الأعمدة الجديدة في بنية البيانات على القرص. وأود أن أكرر الخطوة 2 ، استكشاف البيانات مع الجداول الترافقية والإحصاءات الوصفية في محاولة للعثور على علاقات مثيرة للاهتمام بديهية للنموذج.
  4. عادة ما يكون ملف المشروع النموذجي حوالي 1 غيغابايت. يتم تنظيم الملفات بطريقة تجعل الصف يتألف من سجل بيانات المستهلك. يحتوي كل صف على نفس عدد الأعمدة لكل سجل. هذا هو الحال دائما.
  5. من النادر جدًا أن أقوم بفرز الصفوف عند إنشاء عمود جديد. ومع ذلك ، من الشائع جدًا بالنسبة لي أن أقوم بفرز الصفوف عند إنشاء التقارير أو إنشاء إحصائيات وصفية. على سبيل المثال ، قد أرغب في إنشاء تكرار بسيط لخط عمل معين ، مثل بطاقات الائتمان للبيع بالتجزئة. للقيام بذلك ، سأختار فقط تلك السجلات التي يكون فيها سطر العمل = التجزئة بالإضافة إلى أي أعمدة أريد الإبلاغ عنها. عند إنشاء أعمدة جديدة ، على أية حال ، سأقوم بسحب جميع صفوف البيانات والأعمدة فقط التي أحتاجها للعمليات.
  6. تتطلب عملية النمذجة أن أحلل كل عمود ، وأنظر إلى علاقات مثيرة للاهتمام مع بعض متغير النتيجة ، وأنشئ أعمدة مركبة جديدة تصف تلك العلاقات. عادة ما يتم تنفيذ الأعمدة التي أستكشفها في مجموعات صغيرة. على سبيل المثال ، سأركز على مجموعة من 20 عمودًا ، فقط تعامل مع قيم العقارات ولاحظ كيفية ارتباطها بالتعثر على قرض. وبمجرد استكشاف تلك الأعمدة وإنشاء أعمدة جديدة ، انتقل بعد ذلك إلى مجموعة أخرى من الأعمدة ، مثل التعليم الجامعي ، وأكرر العملية. ما أفعله هو إنشاء المتغيرات المرشحة التي تشرح العلاقة بين بياناتي وبعض النتائج. في نهاية هذه العملية ، أطبق بعض تقنيات التعلم التي تنشئ معادلة خارج تلك الأعمدة المركبة.

من النادر أن أقوم بإضافة صفوف إلى مجموعة البيانات. سأقوم دائمًا بإنشاء أعمدة جديدة (متغيرات أو ميزات في لغة التعلم الإحصائي / الآلي).


أعتقد أن الإجابات الواردة أعلاه تفتقد إلى نهج بسيط وجدته مفيدًا للغاية.

عندما يكون لدي ملف كبير جدًا لتحميله في الذاكرة ، أقوم بتقسيم الملف إلى ملفات أصغر متعددة (إما عن طريق الصف أو الأعمدة)

مثال: في حالة 30 يومًا من بيانات التداول بحجم ~ 30 غيغابايت ، أقوم بتقسيمها إلى ملف لكل يوم بحجم ~ 1 غيغابايت. أقوم بعد ذلك بمعالجة كل ملف على حدة وإجمالي النتائج في النهاية

واحدة من أكبر المزايا هي أنها تسمح بالتعامل المتوازي للملفات (إما خيوط أو عمليات متعددة)

الميزة الأخرى هي أن معالجة الملف (مثل إضافة / إزالة التواريخ في المثال) يمكن تحقيقها بواسطة أوامر shell العادية ، والتي لا تكون ممكنة في تنسيقات ملفات أكثر تقدمًا / تعقيدًا

لا يغطي هذا الأسلوب جميع السيناريوهات ، ولكنه مفيد جدًا في الكثير منها


أعرف أن هذا خيط قديم ولكن أعتقد أن مكتبة Blaze تستحق التدقيق. لقد بنيت لهذا النوع من المواقف.

من المستندات:

ويمدد Blaze إمكانية استخدام NumPy و Pandas للحوسبة الموزعة وغير الأساسية. يوفر Blaze واجهة تشبه واجهة NumPy ND-Array أو Pandas DataFrame ولكنها تحدد هذه الواجهات المألوفة على مجموعة متنوعة من المحركات الحسابية الأخرى مثل Postgres أو Spark.

تعديل: بالمناسبة ، يدعمه ContinuumIO و Travis Oliphant ، مؤلف NumPy.


إذا كانت مجموعات البيانات لديك تتراوح بين 1 و 20 غيغابايت ، فيجب أن تحصل على محطة عمل بسعة ذاكرة عشوائية 48 جيجابايت. ثم يمكن لل Pandas عقد مجموعة البيانات بأكملها في ذاكرة الوصول العشوائي. لا أعرف الإجابة التي تبحث عنها هنا ، ولكن القيام بحوسبة علمية على كمبيوتر محمول مع ذاكرة وصول عشوائي بحجم 4 جيجابايت ليس معقولاً.


ضع في اعتبارك Ruffus إذا ذهبت إلى المسار البسيط لإنشاء خط أنابيب البيانات الذي تم تقسيمه إلى عدة ملفات أصغر.


كما لوحظ من قبل الآخرين ، بعد بضع سنوات برزت " dask " غير المتكافئة "الباندا": dask . على الرغم من أن dask ليس بديلًا عن استبدال الباندا وكل وظائفها ، إلا أنها تبرز لعدة أسباب:

داسك هي مكتبة حاسوبية متوازية مرنة للحوسبة التحليلية التي تم تحسينها من أجل جدولة المهام الديناميكية لأحمال العمل التفاعلية التفاعلية لمجموعات "البيانات الكبيرة" مثل المصفوفات المتوازية ، وأطر البيانات ، والقوائم التي تمد واجهات مشتركة مثل NumPy ، Pandas ، أو python إلى أكبر من الذاكرة أو البيئات الموزعة والمقاييس من أجهزة الكمبيوتر المحمولة إلى مجموعات.

يؤكد داسك على الفضائل التالية:

  • مألوفة: توفر مجموعة NumPy المتوازية وأشياء Pandas DataFrame
  • مرنة: توفر واجهة جدولة المهام لمزيد من أحمال العمل المخصصة والتكامل مع المشروعات الأخرى.
  • Native: لتمكين الحوسبة الموزعة في Python Pure مع الوصول إلى مكدس PyData.
  • سريع: يعمل مع انخفاض الحمل ، وانخفاض الكمون ، والحد الأدنى من التسلسل اللازم للخوارزميات الرقمية السريعة
  • الارتفاعات: تعمل بمرونة على مجموعات تحتوي على 1000s من النوى. مقاييس لأسفل: تافهة لإعداد وتشغيل جهاز كمبيوتر محمول في عملية واحدة
  • متجاوبة: مصممة مع الحوسبة التفاعلية في الاعتبار أنها توفر التغذية الراجعة السريعة والتشخيص لمساعدة البشر

ولإضافة عينة رمز بسيطة:

import dask.dataframe as dd
df = dd.read_csv('2015-*-*.csv')
df.groupby(df.user_id).value.mean().compute()

يستبدل بعض كود الباندا كما يلي:

import pandas as pd
df = pd.read_csv('2015-01-01.csv')
df.groupby(df.user_id).value.mean()

، ولا سيما الجدير بالملاحظة ، يوفر من خلال واجهة المتزامنة.الاتفاقية العامة لتقديم المهام المخصصة:

from dask.distributed import Client
client = Client('scheduler:port')

futures = []
for fn in filenames:
    future = client.submit(load, fn)
    futures.append(future)

summary = client.submit(summarize, futures)
summary.result()

لقد لاحظت هذا متأخرا قليلا ، لكنني أعمل مع مشكلة مماثلة (نماذج الدفع المسبق الرهن العقاري). وكان الحل الخاص بي لتخطي طبقة HDFStore الباندا واستخدام أجهزة الكمبيوتر المحمولة على التوالي. أقوم بحفظ كل عمود كمجموعة HDF5 فردية في ملفي النهائي.

سير العمل الأساسي الخاص بي هو الحصول أولاً على ملف CSV من قاعدة البيانات. أنا gzip ، لذلك ليست ضخمة. ثم أقوم بتحويل ذلك إلى ملف HDF5 ذو توجّه صف ، بتكراره في python ، بتحويل كل صف إلى نوع بيانات حقيقي ، وكتابته إلى ملف HDF5. يستغرق ذلك بضع عشرات من الدقائق ، ولكنه لا يستخدم أي ذاكرة ، نظرًا لأنه يعمل على صف واحد فقط. ثم أنا "تبديل" ملف HDF5 الصف المنحى إلى ملف HDF5 عمود المنحى.

يبدو الجدول المنقولة مثل:

def transpose_table(h_in, table_path, h_out, group_name="data", group_path="/"):
    # Get a reference to the input data.
    tb = h_in.getNode(table_path)
    # Create the output group to hold the columns.
    grp = h_out.createGroup(group_path, group_name, filters=tables.Filters(complevel=1))
    for col_name in tb.colnames:
        logger.debug("Processing %s", col_name)
        # Get the data.
        col_data = tb.col(col_name)
        # Create the output array.
        arr = h_out.createCArray(grp,
                                 col_name,
                                 tables.Atom.from_dtype(col_data.dtype),
                                 col_data.shape)
        # Store the data.
        arr[:] = col_data
    h_out.flush()

قراءتها مرة أخرى تبدو كالتالي:

def read_hdf5(hdf5_path, group_path="/data", columns=None):
    """Read a transposed data set from a HDF5 file."""
    if isinstance(hdf5_path, tables.file.File):
        hf = hdf5_path
    else:
        hf = tables.openFile(hdf5_path)

    grp = hf.getNode(group_path)
    if columns is None:
        data = [(child.name, child[:]) for child in grp]
    else:
        data = [(child.name, child[:]) for child in grp if child.name in columns]

    # Convert any float32 columns to float64 for processing.
    for i in range(len(data)):
        name, vec = data[i]
        if vec.dtype == np.float32:
            data[i] = (name, vec.astype(np.float64))

    if not isinstance(hdf5_path, tables.file.File):
        hf.close()
    return pd.DataFrame.from_items(data)

الآن ، أقوم بتشغيل هذا بشكل عام على جهاز به الكثير من الذاكرة ، لذلك قد لا أكون حذراً بما فيه الكفاية باستخدام الذاكرة الخاصة بي. على سبيل المثال ، افتراضيًا ، تقوم عملية التحميل بقراءة مجموعة البيانات بالكامل.

هذا عموما يعمل بالنسبة لي ، لكنه قليلا عالي الكعب ، وأنا لا يمكن استخدام السحر الهذيان pytables.

تحرير: الميزة الحقيقية لهذا الأسلوب ، عبر افتراضات pytables للمصفوفات ، هي أنه يمكنني تحميل البيانات في R باستخدام h5r ، والتي لا يمكنها التعامل مع الجداول. أو ، على الأقل ، لم أتمكن من تحميله على جداول غير متجانسة.


هذا هو الحال بالنسبة pymongo. لدي أيضا النماذج الأولية باستخدام مزود خدمة ، sqlite ، HDF ، ORM (SQLAlchemy) في بيثون. أولاً وقبل كل شيء ، فإن pymongo عبارة عن مستند يستند إلى مستند ، لذلك يكون كل شخص مستندًا ( dict of attributes). كثير من الناس يشكلون مجموعة ويمكن أن يكون لديك العديد من المجموعات (الناس ، سوق الأوراق المالية ، الدخل).

pd.dateframe -> pymongo ملاحظة: يمكنني استخدام chunksize في read_csv للاحتفاظ به إلى سجلات 5k 10 (pymongo يسقط مأخذ التوصيل إذا كان أكبر)

aCollection.insert((a[1].to_dict() for a in df.iterrows()))

الاستعلام: gt = أكبر من ...

pd.DataFrame(list(mongoCollection.find({'anAttribute':{'$gt':2887000, '$lt':2889000}})))

.find() يعود مكرر لذلك أنا عادة استخدام ichunked إلى ichunked التكرار الأصغر.

ماذا عن الانضمام منذ أن أحصل عادةً على 10 مصادر بيانات للصقها معًا:

aJoinDF = pandas.DataFrame(list(mongoCollection.find({'anAttribute':{'$in':Att_Keys}})))

ثم (في حالتي في بعض الأحيان لا بد لي من agg على aJoinDF أولا قبل "mergeable".)

df = pandas.merge(df, aJoinDF, on=aKey, how='left')

ويمكنك بعد ذلك كتابة المعلومات الجديدة إلى مجموعتك الرئيسية عبر طريقة التحديث أدناه. (المجموعة المنطقية مقابل مصادر البيانات المادية).

collection.update({primarykey:foo},{key:change})

في عمليات البحث الأصغر ، قم بتسميته. على سبيل المثال ، لديك رمز في المستند فقط إضافة نص رمز الحقل وقم بإجراء بحث dict أثناء إنشاء المستندات.

الآن لديك مجموعة بيانات لطيفة حول شخص ، يمكنك إطلاق العنان لمنطقك في كل حالة وجعل المزيد من الصفات. أخيرا يمكنك أن تقرأ في الباندا الخاص بك 3 إلى مؤشرات رئيسية في الذاكرة القصوى والقيام باستكشافات المحاور / agg / data. هذا يعمل بالنسبة لي لمدة 3 ملايين السجلات مع الأرقام / نص كبير / فئات / رموز / يطفو / ...

يمكنك أيضًا استخدام الطريقتين المضمنتين في MongoDB (إطار MapReduce والإجمالي). انظر هنا لمزيد من المعلومات حول الإطار الكلي ، حيث يبدو أنه أسهل من MapReduce ويبدو مفيدًا للعمل التجميعي السريع. إشعار لم أكن بحاجة إلى تحديد حقول أو علاقاتي ، ويمكنني إضافة عناصر إلى مستند. في الحالة الراهنة من متكتل متكتل بسرعة ، الباندا ، أدوات python ، MongoDB يساعدني فقط على العمل :)


هناك الآن ، بعد عامين من السؤال ، ما يعادل "الباندا" خارج الأساسية: dask . ممتاز! على الرغم من أنها لا تدعم جميع وظائف الباندا ، إلا أنه يمكنك فعل ذلك.


واحد أكثر الاختلاف

يمكن إجراء العديد من العمليات التي تتم في حيوانات الباندا أيضًا كاستعلام db (sql، mongo)

يتيح لك استخدام RDBMS أو mongodb تنفيذ بعض المجموعات في استعلام DB (الذي تم تحسينه للبيانات الكبيرة ، ويستخدم ذاكرة التخزين المؤقت والفهارس بكفاءة)

في وقت لاحق ، يمكنك إجراء معالجة ما بعد استخدام الباندا.

تكمن ميزة هذه الطريقة في حصولك على تحسينات DB للعمل مع البيانات الكبيرة ، مع تحديد المنطق في صيغة تفصيلية عالية المستوى - وعدم الاضطرار إلى التعامل مع تفاصيل تقرير ما يجب فعله في الذاكرة وما يجب فعله من جوهر.

وعلى الرغم من اختلاف لغة الاستعلام وحيوانات الباندا ، فليس من المعتاد عادة ترجمة جزء من المنطق من واحد إلى آخر.





large-data