Wiederholen Sie die Power BI-Kohortenanalyse mit Python

Guten Tag, liebe Leser! Der Grund für das Schreiben dieser Veröffentlichung war ein Webinar, das ich mir auf Youtube angesehen habe. Er widmete sich einer Kohortenanalyse des Umsatzes. Der Autor verwendete die Power BI Desktop-Plattform, um mit Daten zu arbeiten. Ich werde keinen Link zu dem angegebenen Video bereitstellen, damit dieser Artikel nicht als Werbung angesehen wird, aber im Verlauf der Erzählung werde ich versuchen, Spoiler zur Originalquelle zu machen, um die Logik meiner eigenen Entscheidung besser zu erklären. Dieses Webinar brachte mich auf die Idee, dass es interessant wäre, die Möglichkeiten von DAX-Formeln mit den Funktionen der Pandas-Bibliothek zu wiederholen.

Zwei Punkte, auf die ich mich konzentrieren möchte. Erstens ist dieses Material für Anfänger-Analysten gedacht, die gerade ihre ersten Schritte in der Verwendung der Programmiersprache Python unternehmen. Ideal, wenn die Leser mit der Power BI BI-Analyseplattform vertraut sind. Zweitens, da DAX-Berechnungen als Inspirationsquelle dienten, werde ich die Algorithmen des Autors so weit wie möglich „kopieren“, und es wird unvermeidlich eine Abweichung von den wichtigsten Programmierparadigmen geben.

Mit der Einführung ist das alles. Lasst uns los fahren!

Wir werden alle Berechnungen in der JupyterLab-Umgebung durchführen. Die Laptop-Lösungen finden Sie unter ( Link ).

Daten werden mit dem Power Query-Tool in Power BI geladen (tatsächlich handelt es sich um einen visuellen Editor, der Abfragen in der Sprache M generiert). Bei der Entwicklung sollten Sie die folgende Regel einhalten: Die gesamte Datenvorverarbeitung sollte mit Power Query erfolgen, und Metriken sollten mit Power Pivot berechnet werden. Da unsere Hauptbibliothek Pandas ist, nutzen wir ihre Funktionen sofort.

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

Wir werden die Codezeilen zur Laufzeit testen, um in Zukunft die zeitaufwändigen Abschnitte zu erstellen. Verwenden Sie die Betriebssystembibliothek, um den vollständigen Pfad zur gelesenen Datei festzulegen. Um die Entwicklung eines Laptops zu vereinfachen, können Sie darauf verzichten. Der Datensatz selbst ist zufällig zusammengesetzt. Die CSV-Datei enthält 1.048.575 Zeilen. Das Lesen von Daten mit der Funktion read_csv () ist normalerweise unkompliziert. Es reicht aus, das Spaltentrennzeichen und die Spalte mit Datumsangaben im Array anzugeben. Wenn die Informationen mit einigen "Funktionen" hochgeladen wurden, müssen Sie möglicherweise zusätzliche Parameter konfigurieren, z. B. die Codierung für jede Spalte angeben.

Die Funktion head () wird häufig verwendet, um den Fortschritt der Datentransformation visuell zu überwachen. Alle Fehler können nicht abgeschnitten werden, aber offensichtliche Fehler können vor Ort behoben werden.

Nach dem Laden der Daten in das Modell sortiert der Autor des Webinars das Datenarray. Dies geschieht, um eine Hilfsspalte mit Indizes hinzuzufügen. In unserem Fall wird diese Spalte nicht verwendet, aber die Daten werden auch sortiert, um die korrekte Berechnung der Felder in den Tabellen bequemer zu steuern.

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

Bild

Im nächsten Schritt schlägt die Lösung auf der Power BI-Plattform vor, eine Hilfstabelle zu erstellen, deren Daten in das Hauptarray gezogen werden. Das Erstellen einer Tabelle erfolgt mit der Funktion SUMMARIZE (). Es wird eine Pivot-Tabelle mit aggregierten Summen für ausgewählte Gruppen erstellt: 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]))

Die Pandas-Bibliothek hat ihr Gegenstück - die groupby () -Funktion. Um groupby () anzuwenden, reicht es aus, den erforderlichen Datenrahmen, gruppierbare Spalten, anzugeben und am Ende die Spalten aufzulisten, für die Aggregationsfunktionen angewendet werden. Das erhaltene Ergebnis wird durch die Funktion reset_index () auf das Format des üblichen Datenrahmens reduziert. Benennen Sie abschließend die Felder um.

%%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

Zusätzlich zur Metrik „Erstes Kaufdatum“ werden die Anzahl der Transaktionen pro Kunde und der Gesamtbetrag der Kundenkäufe für den gesamten Zeitraum berechnet. Die Messungen haben ihre Anwendung im Laptop nicht gefunden, aber wir werden sie nicht entfernen.

Wir kehren zum Webinar zurück. Die neue Metrik "Jahr-Monat des ersten Kaufs" wird berechnet. DAX-Formel: first_transaction = FORMAT(df_groupby_user[first_date_transaction];"YYYY-MM")

Bild

Python verwendet die Syntax dt.strftime ('% Y-% m'). Eine ausführliche Erklärung zur Funktionsweise in Online-Veröffentlichungen zum Arbeiten mit Datum und Uhrzeit in Python finden Sie. In diesem Schritt ist etwas anderes wichtig. Achten Sie auf den Zeitpunkt der Operation.

Überhaupt keine pandasähnliche Leistung (24,8 Sek.). Die Codezeile ist langsamer als alle vorherigen.
Diese Auflistung wird der erste Kandidat für ein mögliches Refactoring.

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

Es ist Zeit, wieder zum Webinar zurückzukehren. Es gibt eine Vereinigung von Tabellen durch ein Schlüsselfeld. Anschließend werden die erforderlichen Felder mit der Funktion RELATED () in die Haupttabelle gezogen. Pandas hat diese Funktion nicht. Aber es gibt merge (), join (), concat (). In diesem Fall ist es am besten, die erste Option anzuwenden.

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

Nachdem die Daten mit dem Datum der ersten Transaktion in die Haupttabelle gefallen sind, können Sie das Delta berechnen. Wir verwenden das Apply-Konstrukt (Lambda x: ...), um deutlich zu machen, wie ressourcenintensiv dieser Prozess ist (39,7 Sek.). Hier ist ein weiterer Kandidat für das Umschreiben von Code.

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

Die Haupttabelle hat bereits ein Delta pro Tag, sodass Sie die Spaltendaten in Kohorten unterteilen können. Prinzip: 0 (dh der erste Verkauf an den Kunden) - Kohorte 0; Werte größer als 0, aber kleiner oder gleich 30 sind 30; Werte größer als 30, aber kleiner oder gleich 90 sind 90 usw. Für diese Zwecke können Sie in DAX die Funktion CEILING () verwenden. Es rundet die Zahl auf die nächste Ganzzahl auf, ein Vielfaches des Wertes aus dem zweiten Parameter.

Bild

In Python habe ich keine ähnliche mathematische Funktion gefunden, obwohl ich geplant hatte, sie im Mathematikmodul zu finden (vielleicht habe ich schlecht gesucht). Daher musste ich herumgehen und die Funktion cut () anwenden. Nach dem Verteilen der Daten in Kohorten wurde NaN auf numerische Werte von 0 abgebildet. Wir können dieses Problem nicht mit der Funktion fillna () lösen, da es sich um kategoriale Daten handelt. Zuerst müssen Sie der Kategorie einen neuen Wert hinzufügen. Ändern Sie am Ende dieser Codeliste den Datentyp in int. Dies geschieht, damit in Zukunft beim Erstellen einer Pivot-Tabelle unter Verwendung eines Datenrahmens die neue Kohorte nicht am Ende einer Reihe von Werten angezeigt wird.

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

Mit der Funktion pivot_table () erhalten wir die gewünschte Pivot-Tabelle. Wir erhalten ziemlich viele Kohorten, so dass das Ergebnis nicht vollständig auf dem Bildschirm angezeigt werden kann. Um dies zu vermeiden, können Sie bei der Lösung eines realen Falls ein kürzeres Zeitintervall für die Analyse verwenden oder die Wertebereiche der Kohorten selbst vergrößern.

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

Bild

In Power BI müssen Sie das Matrix-Tool verwenden, um eine solche Visualisierung zu erstellen.

Bild

Die nächste Stufe ist das Plotten. Die Nuance der Situation ist, dass wir den Betrag periodengerecht benötigen. Wählen Sie in Power BI einfach den gewünschten Menüpunkt "Schnellaktion" aus, und die erforderliche DAX-Formel wird automatisch generiert. Mit der Pandas-Bibliothek ist die Situation etwas komplizierter. Wir gruppieren den vorhandenen Datenrahmen doppelt nacheinander und wenden die Funktion cumsum () an. Da das Ergebnis weiterhin verwendet wird, erstellen wir eine Kopie des Datenrahmens, um das Diagramm zu erstellen. Die kumulierten Verkaufswerte waren ziemlich groß, daher teilen wir die Werte durch 1.000.000 und runden das Ergebnis nach dem Dezimalpunkt auf zwei Ziffern.

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

Wir verwenden die Funktionen der Bibliothek, um das Diagramm zu erstellen. Ein Diagramm besteht nur aus einer Codezeile, aber das Ergebnis ist nicht beeindruckend. Dieses Diagramm verliert deutlich an Visualisierungen auf jeder BI-Plattform. Sie können die Plotly-Bibliothek verbinden und mit Add-Ons zaubern. Dies sind jedoch völlig andere Arbeitskosten als im Video gezeigt.

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

Bild

Lassen Sie uns kurze Schlussfolgerungen ziehen.

In Bezug auf Berechnungen kann die Pandas-Bibliothek Power Pivot (DAX) ersetzen.

Die Machbarkeit eines solchen Ersatzes bleibt außerhalb des Gesprächs.

DAX führt wie die Funktionen der Python-Bibliothek gute Operationen für ganze Felder einer Tabelle aus.

In Bezug auf Geschwindigkeit, Einfachheit und einfache Visualisierung ist Power BI Pandas überlegen. Meiner Meinung nach sind die integrierten Diagramme (sowie die mit der Matplotlib erstellten Bibliotheken für Meeresgeborene) in zwei Fällen geeignet: Expressanalyse einer Reihe von Daten für Ausreißer, lokale Minima / Maxima oder Vorbereitung von Folien für die Präsentation. Die Entwicklung grafischer Bedienfelder ist am besten BI-Lösungen überlassen.

Das ist alles. Alle Gesundheit, viel Glück und beruflichen Erfolg!

All Articles