尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

如何计算 DAX 中多个周期的移动平均

如何计算 DAX 中多个周期的移动平均
📅 发布时间:2026/6/19 10:22:38

原文:towardsdatascience.com/how-to-calculate-a-moving-average-over-multiple-periods-in-dax-2a6a8105850a?source=collection_archive---------13-----------------------#2024-10-01

在 DAX 中计算移动聚合是很简单的。然而,当计算跨时间的移动平均时,会有一些陷阱。由于其中一些陷阱涉及定义的问题,我们必须小心不要选择错误的方法。让我们来看看具体细节。

https://medium.com/@salvatorecagliari?source=post_page---byline--2a6a8105850a--------------------------------https://towardsdatascience.com/?source=post_page---byline--2a6a8105850a-------------------------------- Salvatore Cagliari

·发表于 Towards Data Science ·8 分钟阅读·2024 年 10 月 1 日

–

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/7302237dcc3ebd4223716fd99aa0982c.png

图片由 Antoine Dautry 提供,来源 Unsplash

首先,先来做一些数学计算。

计算平均数很简单:将值的总和除以实例的数量。

虽然值的总和很容易计算,但实例的数量并不像你想象的那样简单。

例如,让我们看一下以下的表格:

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/e823e254f4774c82fcf9f9152255ce0b.png

图 1 — 数字列表(图源:作者)

计算值列的平均数很简单:

<值的总和> / <行数> = 534.68 / 10 = 53.47

现在,让我们删除一个值,这会改变结果。

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/3f55fc4390557dacc0c69ebcf2253745.png

图 2 — 带有间隙的数字列表(图源:作者)

突然间,我有两种计算平均数的方法:

<值的总和> / <值的数量> = 547.23 / 9 = 60.8

或者

<值的总和> / <行数> = 547.23 / 10 = 54.72

第二种方法仅仅是不同的定义。

比如,假设第一列是客户 ID,我想计算所有客户的平均销售额或活跃客户的数量等情况,在这种情况下,第二种计算平均数的方法可能是更好的选择。

现在,让我们将其转换为 DAX。

移动聚合 — 起点

首先,让我们构建移动聚合的典型案例。

我想要获取过去四个月的移动销售数据。

目前,我使用 SUM() 的销售数据,因为比起计算平均值,验证四个月的结果要容易得多。

Sales Moving Sum=VAR MaxDate=MAX('Date'[Date])VAR MinDate=CALCULATE(MIN('Date'[Date]),DATEADD('Date'[Date],-3,MONTH))VAR DateRange=CALCULATETABLE(DATESBETWEEN('Date'[Date],MinDate,MaxDate))VAR Result=CALCULATE([Sum Online Sales],DateRange)RETURN Result

首先,我获取当前筛选上下文(例如当前月份)的最后日期

第二,我使用 DATEADD() 来回退三个月。我只回退三个月,因为我包括了当前月。

如果我想排除当前月份,我必须以不同的方式操作。在这种情况下,我需要获取第一个日期,并回退一天来获取上个月的最后日期(或者使用 [EOMONTH(MAX(‘Date’Date), -1) ),然后使用 DATEADD() 回退四个月)。

第三,我使用 DATESBETWEEN() 获取两个变量之间的日期列表。

最后,我将日期列表传递给 CALCULATE() 来返回最终结果。

这是结果:

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/f74e57bca2c2fb4c51a08e5621c5e4a6.png

图 3 — 四个月移动总和的表格(图由作者提供)

我可以通过移除 DATESBETWEEN() 函数,并将两个变量直接传递给 CALCULATE() 来简化度量值:

VAR MaxDate=MAX('Date'[Date])VAR MinDate=CALCULATE(MIN('Date'[Date]),DATEADD('Date'[Date],-1,MONTH))VAR Result=CALCULATE([Sum Online Sales],'Date'[Date]>=MinDate&&'Date'[Date]<=MaxDate)RETURN Result

结果是相同的,但使用 DATESBETWEEN() 的性能略好(我的事实表中有 1700 万行数据)。

由于多种因素可能会影响性能,我建议你使用自己的数据和使用场景尝试这两种变体,并检查差异。

你可以在这里关于在 Power BI 中衡量性能的内容:

## 如何通过 DAX Studio 从 Power BI 获取性能数据

有时我们会遇到报告加载缓慢的情况,我们需要找出原因。接下来我们将看到如何收集性能数据,以及……

[towardsdatascience.com

我们来做平均值

现在,最终,我将开始计算平均值。

我使用与我的 Sum Online Sales 度量值相同的逻辑,并使用 AVERAGEX() 来计算平均销售额:

Average Online Sales=AVERAGEX('Online Sales',('Online Sales'[UnitPrice]*'Online Sales'[SalesQuantity])-'Online Sales'[DiscountAmount])

接下来,我复制了上述度量值来计算销售移动平均值,结果如下:

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/68a11c25a254d6ac8343512c4a3dcd29.png

图 4 — 基本平均值和移动平均值的结果(图由作者提供)

我可以在这里结束并写道,“任务完成。”但请停一下。

在开始时,我提到了计算平均值的不同方法。

所以,我开始编写度量值来进行测试。

我编写了以下度量值,作为分母,而使用了[Sum Online Sales]作为分子:

  • 计算在线销售数量 = COUNTROWS(‘Online Sales’)

  • 客户数量 = DISTINCTCOUNT(‘Online Sales’[CustomerKey])

  • 在线订单数量 = DISTINCTCOUNT(‘Online Sales’[SalesOrderNumber])

结果变量的代码如下(以[在线销售计数]为例):

VAR Result=CALCULATE([Sum Online Sales]/[Count Online Sales],DateRange)

我可以想到更多的变体(例如,计算所有客户的平均值,包括那些在该期间没有订单的客户)。但我决定在此停止,以避免混淆。

毫不奇怪,每个都得出了不同的结果:

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/813bde70d788d62be9a52ccab2bd4a81.png

图 5 — 所有变体的平均值结果(图表由作者提供)

结果之间的差异非常明显。

你可能会遇到其他计算平均值的方法。

因此,我强烈建议你清楚地定义如何计算平均值。否则,你可能会向你的受众提供意外的甚至错误的结果。

按月销售额的平均值

计算平均值时还有一种变体:作为按月销售额的平均值。

让我们再看一下包含月度销售额的结果:

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/32643cadbfedf8807b3a6c869a8ece00.png

图 6 — 仅月度销售额(图表由作者提供)

我想计算四个月的月度销售平均值。

例如,在九月,我想计算六月、七月、八月和九月的月度销售平均值:

(275’061’552.33 + 303’302’950.82 + 273’004’268.56 + 262’971’889.59) / 4 = ~278’585’165.3

(~ 因为由于四舍五入差异,我们可能会得到稍有不同的结果)

为了满足这个需求,我必须思考如何做。

我需要提前计算每个月的销售额。然后仅考虑每行所需的四个月。最后,计算这四个值的平均值。

这意味着我必须首先生成一个包含所有月度结果的表格,并仅使用计算平均值所需的值,这样效率低下。然后 Power BI 会为表格中的每一行计算这个值,以可视化结果。

当我从每行的过滤器上下文的角度来看时,我可以做得更好。

为什么不只为每行在可视化中相关的那些月份计算销售总和呢?

基于这种方法,我编写了以下度量:

Moving Average by Month=//1\.Get the firstandlast Dateforthe current Filter Context VAR MaxDate=MAX('Date'[Date])VAR MinDate=CALCULATE(MIN('Date'[Date]),DATEADD('Date'[Date],-3,MONTH))//2\.Generate the Daterangeneededforthe Moving average(Four months)VAR DateRange=CALCULATETABLE(DATESBETWEEN('Date'[Date],MinDate,MaxDate))//3\.Generate a table filtered by the Date Range generated at step2//This table contains only four rows VAR SalesByMonth=CALCULATETABLE(SUMMARIZECOLUMNS('Date'[MonthKey],"#Sales",[Sum Online Sales]),DateRange)RETURN//4\.Calculate the Average over the four valuesinthe table generatedinStep3AVERAGEX(SalesByMonth,[#Sales])

这次,我添加了内联注释来解释那里的情况。

结果如下:

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/c43bd7dbe2d5df7b7757915109037d8b.png

图 7 — 按月平均值的结果(图表由作者提供)

我在 Excel 中检查了结果,它们是正确的。

如果你正在考虑为每个月创建一个预计算表格,再考虑一下吧。

你将被迫向所有维度添加引用,并增加数据的粒度,直到你不得不编写这个度量来满足受众按所有维度筛选数据的需求。

这个解决方案非常高效,因为计算结果花费的时间不到 0.4 秒。

即使扩展所有月份,计算结果也不需要更多的时间。

顺便提一下,这种方法在计算平均值的平均数时也很适用。

结论

平均值不等于平均值。我想这点很清楚。

但更重要的是,必须理解应该计算什么,以及如何计算。

理解为什么需要计算一个数字,有助于你选择正确的计算逻辑。

当逻辑清晰时,编写 DAX 代码的方法应当被确定。记住,从筛选上下文的角度来做。有时这可能不直观,但它将有助于开发高效的代码。

希望你今天学到了新东西。

下次见。

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/c8f7f0a0de78dae8db3e34fce94e1731.png

图片由Tim Mossholder拍摄,来自Unsplash

参考文献

像我之前的文章一样,我使用的是 Contoso 示例数据集。你可以从微软这里免费下载 ContosoRetailDW 数据集。

如这里所述,Contoso 数据可以在 MIT 许可下自由使用。

我更改了数据集,将数据移动到当代日期。

[## 当 Salvatore Cagliari 发布新文章时,获取电子邮件通知。

当 Salvatore Cagliari 发布新文章时,你会收到电子邮件通知。通过注册,你将创建一个 Medium 账户,如果你还没有的话……

medium.com](https://medium.com/@salvatorecagliari/subscribe?source=post_page-----2a6a8105850a--------------------------------)

尽管 Medium 设置了付费墙,我仍让我的文章对所有人可读。这让我能从每个读者那里赚取一些费用,但我关闭了它,所以你可以免费阅读我的文章。

我在晚上和周末写这些文章,这是一项繁重的工作。

你可以通过以下方式支持我的工作:

buymeacoffee.com/salvatorecagliari

或扫描此二维码:

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/e7ac062070dcd7a00dcf995ad7e95434.png

任何支持都将不胜感激,并帮助我找到更多时间为你创作更多内容。

非常感谢。

相关新闻

  • Arduino Nano中ATmega328P的PWM输出配置实战案例
  • 如何挑战自己的分析,避免他人挑战
  • MDK在分布式控制系统中的实践案例

最新新闻

  • 深圳黄金回收实测指南,六大本地奢品门店走访测评 - 薛定谔的梨花猫
  • 2026 宁波闲置名包处置全测评:正规连锁门店横向对比,看懂皮具估价底层逻辑 - 奢侈品回收评测
  • 渭南黄金回收指南:六家靠谱店铺推荐,覆盖全市区县安心变现 - 清奢黄金上门回收
  • 阿拉善盟黄金回收去哪儿好?整理了5家靠谱实体店地址电话 - 奢金汇
  • 2026西宁黄金回收白银回收铂金回收门店+工商公安双备案+中检认证商家推荐 - 诚金汇钻回收公司
  • 2026苏州大额黄金回收测评|对公个人双合规,收的顶资金安全兜底 - 奢侈品回收测评

日新闻

  • 5分钟掌握Python进化算法:Geatpy高性能优化工具完全指南
  • Microchip 24AA044 EEPROM选型与应用全指南:从参数解析到实战编程
  • 华为的鸿蒙到底有多牛?为什么称作遥遥领先?

周新闻

  • 3步解锁iOS设备:applera1n激活锁绕过完全指南
  • 39 2026 人工智能证书终极盘点,普通人选 AI 证书可以从这些方向入手
  • Redis 暴露公网有多危险?从端口检查到补救步骤

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号