كرر تحليل مجموعة Power BI باستخدام Python

مساء الخير أيها القراء! كان سبب كتابة هذا المنشور ندوة عبر الإنترنت ، نظرت فيها على يوتيوب. كان مخصصًا لإجراء تحليل جماعي للمبيعات. استخدم المؤلف نظام Power BI Desktop للعمل مع البيانات. لن أقدم رابطًا للفيديو المحدد حتى لا يتم اعتبار هذه المقالة كإعلان ، ولكن في سياق السرد سأحاول أن أفسد المصدر الأصلي من أجل شرح منطق قراري بشكل أفضل. أعطاني هذا البرنامج التعليمي على الويب فكرة أنه سيكون من المثير للاهتمام تكرار إمكانيات صيغ DAX مع وظائف مكتبة Pandas.

نقطتان أريد التركيز عليهما. أولاً ، هذه المادة مخصصة للمحللين المبتدئين الذين يتخذون خطواتهم الأولى في استخدام لغة برمجة Python. مثالية إذا كان القراء على دراية بمنصة التحليلات Power BI BI. ثانيًا ، نظرًا لأن حسابات DAX كانت بمثابة مصدر للإلهام ، فسأقوم "بنسخ" خوارزميات المؤلف إلى أقصى حد ممكن ، ولا بد أن يكون هناك خروج عن نماذج البرمجة الرئيسية.

مع المقدمة ، هذا كل شيء. لنصل الى الطريق!

سنقوم بجميع الحسابات في بيئة JupyterLab. يمكن العثور على حلول الكمبيوتر المحمول على ( link ).

يتم تحميل البيانات في Power BI باستخدام أداة Power Query (في الواقع ، هو محرر مرئي يقوم بإنشاء استعلامات باللغة M). يجب اتباع القاعدة التالية أثناء التطوير: يجب أن تتم جميع عمليات المعالجة المسبقة للبيانات باستخدام Power Query ، ويجب حساب المقاييس باستخدام Power Pivot. نظرًا لأن مكتبتنا الرئيسية هي Pandas ، فإننا نستخدم قدراتها على الفور.

%%time
#   
path_to_data = "C:/Users/Pavel/Documents/Demo/"
# 
df = pd.read_csv(os.path.join(path_to_data, "ohortAnalysis_2016_2018.csv"), sep=";", parse_dates=["date"], dayfirst=True)

سنقوم باختبار سطور التعليمات البرمجية في وقت التشغيل من أجل إنشاء الأقسام الأكثر استهلاكًا للوقت في المستقبل. لتعيين المسار الكامل للملف المقروء ، استخدم مكتبة os. لتبسيط عملية تطوير جهاز كمبيوتر محمول ، يمكنك الاستغناء عنه. تتكون مجموعة البيانات نفسها بشكل عشوائي. يوجد 1،048،575 سطر في ملف CSV. عادة ما تكون قراءة البيانات باستخدام وظيفة read_csv () مباشرة. يكفي تحديد فاصل العمود والعمود بتواريخ ، إن وجدت ، في الصفيف. إذا تم تحميل المعلومات مع بعض "الميزات" ، فقد تحتاج إلى تكوين معلمات إضافية ، على سبيل المثال ، تحديد الترميز لكل عمود.

غالبًا ما يتم استخدام وظيفة head () في الحالة لرصد تقدم تحويل البيانات بشكل مرئي. لا يمكن قطع جميع الأخطاء ، ولكن يمكن إصلاح العيوب الواضحة على الفور.

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

%%time
#  ,      
df.sort_values(["user_id","date"], inplace = True)

صورة

في الخطوة التالية ، يقترح الحل على منصة Power BI إنشاء جدول إضافي ، سيتم سحب البيانات منه إلى الصفيف الرئيسي. يتم إنشاء جدول باستخدام دالة SUMMARIZE (). يقوم بإنشاء جدول محوري بإجماليات مجمعة للمجموعات المحددة: df_groupby_user = SUMMARIZE(df;df[user_id];"first_date_transaction";MIN(df[date]);"total_amount_user";SUM(df[amount]);"count_transaction_user";COUNT(df[amount]))

تحتوي مكتبة Pandas على نظيرتها - وظيفة groupby (). لتطبيق groupby () يكفي تحديد إطار البيانات اللازم ، الأعمدة القابلة للتجميع ، في نهاية القائمة الأعمدة التي سيتم تطبيق وظائف التجميع لها. يتم تقليل النتيجة التي تم الحصول عليها إلى تنسيق إطار البيانات المعتاد بواسطة وظيفة reset_index (). في الختام ، أعد تسمية الحقول.

%%time
#       user_id. 
df_groupby_user = df.groupby(by = ["user_id"]).agg({"date": "min", "amount": ["sum","count"]})
df_groupby_user.reset_index(inplace = True)
# 
new_columns = ["user_id","first_date_transaction", "total_amount_user","count_transaction_user"]
df_groupby_user.columns = new_columns

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

نعود إلى الويبينار. يتم حساب المقياس الجديد "سنة الشراء الأولى". صيغة DAX: first_transaction = FORMAT(df_groupby_user[first_date_transaction];"YYYY-MM")

صورة

تستخدم Python بناء الجملة dt.strftime ('٪ Y-٪ m'). ستجد شرحًا تفصيليًا لكيفية عملها في المنشورات عبر الإنترنت فيما يتعلق بالعمل مع التاريخ والوقت في Python. في هذه الخطوة ، هناك شيء آخر مهم. انتبه إلى وقت العملية.

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

%%time
#  -
df_groupby_user["first_transaction"] = df_groupby_user["first_date_transaction"].dt.strftime('%Y-%m')

حان الوقت للعودة إلى الندوة مرة أخرى. يوجد اتحاد الجداول حسب مجال رئيسي. ثم يتم سحب الحقول الضرورية إلى الجدول الرئيسي باستخدام دالة RELATED (). لا تمتلك Pandas هذه الميزة. ولكن هناك دمج () ، انضمام () ، concat (). في هذه الحالة ، من الأفضل تطبيق الخيار الأول.

%%time
# 
df_final = pd.merge(df, df_groupby_user, how = "left", on = "user_id")

بعد أن تقع البيانات بتاريخ المعاملة الأولى في الجدول الرئيسي ، يمكنك حساب الدلتا. نستخدم بنية التطبيق (lambda x: ...) لتوضيح مدى كثافة هذه العملية (39.7 ثانية). هنا مرشح آخر لإعادة كتابة التعليمات البرمجية.

%%time
#   "    "
df_final["delta_days"] = df_final["date"] - df_final["first_date_transaction"]
df_final["delta_days"] = df_final["delta_days"].apply(lambda x: x.days)

يحتوي الجدول الرئيسي بالفعل على دلتا حسب اليوم ، لذلك يمكنك تقسيم بيانات العمود إلى مجموعات نموذجية. المبدأ: 0 (أي البيع الأول للعميل) - المجموعة 0 ؛ القيم أكبر من 0 ، ولكن أقل من أو يساوي 30 هي 30 ؛ القيم الأكبر من 30 ، ولكن أقل من أو يساوي 90 هي 90 ، إلخ. لهذه الأغراض ، في DAX ، يمكنك استخدام الدالة CEILING (). لتقريب الرقم إلى أقرب عدد صحيح ، مضاعف القيمة من المعلمة الثانية.

صورة

في بايثون ، لم أجد وظيفة رياضية مماثلة ، على الرغم من أنني خططت للعثور عليها في وحدة الرياضيات (ربما بحثت بشكل سيء). لذلك ، كان علي أن أذهب وتطبيق الدالة cut (). بعد نشر البيانات في مجموعات نموذجية ، تم تعيين NaN إلى قيم عددية 0. لا يمكننا حل هذه المشكلة باستخدام دالة fillna () ، حيث أننا نتعامل مع البيانات الفئوية. تحتاج أولاً إلى إضافة قيمة جديدة إلى الفئة. في نهاية قائمة التعليمات البرمجية هذه ، قم بتغيير نوع البيانات إلى int. يتم ذلك بحيث أنه في المستقبل ، عند إنشاء جدول محوري باستخدام إطار بيانات ، لا تظهر المجموعة النموذجية الجديدة في نهاية سلسلة من القيم.

%%time
#  . 
cut_labels_days = [x for x in range (30, 1230, 30)]
cut_bins_days = [x for x in range (0, 1230, 30)]
df_final["cohort_days"] = pd.cut(df_final["delta_days"], bins = cut_bins_days, labels=cut_labels_days, right = True)
%%time
#     .   fillna   !
df_final["cohort_days"] = df_final["cohort_days"].cat.add_categories([0])
df_final["cohort_days"].fillna(0, inplace = True)
%%time
#     .   fillna   !
df_final["cohort_days"] = df_final["cohort_days"].cat.add_categories([0])
df_final["cohort_days"].fillna(0, inplace = True)
#    .    ,  "0"        ,     
#    .
df_final["cohort_days"] = df_final["cohort_days"].astype(int)

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

%%time
#  
df_pivot_table = pd.pivot_table(df_final, values=["amount"], index=["first_transaction"], columns=["cohort_days"], aggfunc=np.sum, fill_value = 0)

صورة

في Power BI ، تحتاج إلى استخدام أداة Matrix لإنشاء مثل هذا التصور.

صورة

المرحلة التالية هي التآمر. الفروق الدقيقة في الوضع هي أننا نحتاج إلى المبلغ على أساس الاستحقاق. في Power BI ، ما عليك سوى تحديد عنصر القائمة "إجراء سريع" المطلوب وسيتم إنشاء صيغة DAX اللازمة تلقائيًا. مع مكتبة Pandas ، فإن الوضع أكثر تعقيدًا قليلاً. نقوم بتجميع إطار البيانات الموجود بشكل تسلسلي مزدوج وتطبيق دالة cumsum (). نظرًا لأن النتيجة ستستمر في استخدامها ، فسنعمل على إنشاء نسخة من إطار البيانات لإنشاء الرسم البياني. كانت قيم المبيعات المتراكمة كبيرة جدًا ، لذلك نقسم القيم على 1،000،000 وتقريب النتيجة إلى رقمين بعد الفاصلة العشرية.

%%time
#     amount
df_pivot_table_cumsum = df_final.groupby(by = ["first_transaction","cohort_days"]).agg({"amount": ["sum"]}).groupby(level=0).cumsum().reset_index()
df_pivot_table_cumsum.columns = ["first_transaction","cohort_days","cumsum_amount"]
%%time
#     
df_pivot_table_cumsum_chart = copy.deepcopy(df_pivot_table_cumsum)
#     ,       Y.
df_pivot_table_cumsum_chart["cumsum_amount"]=round(df_pivot_table_cumsum_chart["cumsum_amount"]/1000000, 2)

نستخدم قدرات المكتبة لبناء الرسم البياني. يتم إنشاء رسم تخطيطي في سطر واحد فقط من التعليمات البرمجية ، ولكن النتيجة ليست مثيرة للإعجاب. يفقد هذا الرسم البياني بوضوح على المرئيات على أي منصة BI. يمكنك توصيل مكتبة Plotly والاستحضار بالوظائف الإضافية ، ولكن هذه تكاليف عمالة مختلفة تمامًا مقارنة بالنهج الموضح في الفيديو.

%%time
df_pivot_table_cumsum_chart.pivot(index="cohort_days", columns="first_transaction", values="cumsum_amount").plot(figsize = (15,11))

صورة

دعونا نصل إلى استنتاجات موجزة.

من حيث الحسابات ، قد تحل مكتبة Pandas محل Power Pivot (DAX).

لا تزال جدوى مثل هذا الاستبدال خارج المحادثة.

تقوم DAX ، مثل وظائف مكتبة Python ، بعمل جيد في تنفيذ العمليات على حقول الجدول بالكامل.

من حيث السرعة والبساطة وسهولة تصميم التصور ، فإن Power BI متفوقة على Pandas. في رأيي ، فإن الرسوم البيانية المدمجة (وكذلك تلك التي تم إنشاؤها باستخدام matplotlib ، المكتبات البحرية) مناسبة للاستخدام في حالتين: تحليل صريح لعدد من البيانات للقيم المتطرفة ، أو الحدود الدنيا / الحدود القصوى المحلية ، أو إعداد الشرائح للعرض التقديمي. من الأفضل ترك تطوير لوحات التحكم الرسومية لحلول BI.

هذا كل شئ. كل الصحة والحظ الجيد والنجاح المهني!

All Articles