使用Python重复Power BI同类群组分析

下午好,亲爱的读者们!撰写此出版物的原因是一个网络研讨会,我在YouTube上看到过。他致力于队列销售分析。作者使用Power BI Desktop平台处理数据。我不会提供指向指定视频的链接,因此不会将此文章视为广告,但是在叙述过程中,我将尝试破坏原始来源,以便更好地解释我自己决定的逻辑。这次网络研讨会使我想到,利用Pandas库的功能重复DAX公式的可能性会很有趣。

我想重点谈两点。首先,本材料面向刚开始使用Python编程语言迈出第一步的初学者。如果读者熟悉Power BI BI分析平台,则是理想的选择。其次,由于DAX计算是灵感的来源,因此我将尽可能“复制”作者的算法,并且不可避免地会偏离主要的编程范例。

通过介绍,仅此而已。让我们上路吧!

我们将在JupyterLab环境中执行所有计算。便携式计算机解决方案可在(链接找到

使用Power Query工具将数据加载到Power BI中(实际上,它是使用M语言生成查询的可视化编辑器)。在开发过程中应遵循以下规则:所有数据预处理都应使用Power Query完成,而度量应使用Power Pivot计算。由于我们的主要图书馆是熊猫,所以我们立即使用其功能。

%%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库。为了简化笔记本电脑的开发过程,您可以不用它。数据集本身是随机组成的。 CSV文件中有1,048,575行。使用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()函数将必要的字段拉入主表。熊猫没有此功能。但是有merge(),join(),concat()。在这种情况下,最好应用第一个选项。

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

将具有第一次交易日期的数据放入主表后,可以计算增量。我们使用apply结构(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()函数。它将数字四舍五入到最接近的整数,该整数是第二个参数的值的倍数。

图片

在Python中,虽然我计划在math模块中找到它(也许搜索不佳),但我没有找到类似的数学函数。因此,我不得不四处应用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中,您需要使用矩阵工具来构建这种可视化。

图片

下一阶段是绘图。情况的细微差别是我们需要权责发生制。在Power BI中,只需选择所需的“快速操作”菜单项,就会自动生成必要的DAX公式。有了熊猫图书馆,情况就更加复杂了。我们对现有的数据帧进行双重排序,并应用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))

图片

让我们做出简短的结论。

在计算方面,熊猫库很可能会取代Power Pivot(DAX)。

这种替换的可行性仍在讨论之外。

DAX和Python库函数一样,在对表的整个字段执行操作方面也做得很好。

在速度,简便性和可视化设计的简便性方面,Power BI优于Pandas。我认为,内置图形(以及使用matplotlib,seaborn库创建的图形)适合在以下两种情况下使用:对异常值,局部最小值/最大值的大量数据进行快速分析,或准备幻灯片进行演示。图形控制面板的开发最好留给BI解决方案。

就这样。一切健康,祝您好运和专业成功!

All Articles