当前位置: 首页 > news >正文

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

在 DAX 中计算移动聚合很容易。但是,计算一段时间内的移动平均值时会有一些陷阱。由于其中一些陷阱是定义问题,因此我们必须小心,不要选择错误的方法。让我们看看细节。欢迎来到雲闪世界。

添加图片注释,不超过 140 字(可选)

首先,一些数学知识

计算平均值很容易:将值的总和除以实例数。

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

例如,我们来看看下表:

图 1 — 数字列表

平均值列的计算很简单:

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

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

图 2 — 有间隙的数字列表

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

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

或者

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

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

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

移动聚合——起点

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

我想要获得过去四个月的搬家销售额。

现在,我使用销售额的SUM(),因为验证四个月的结果比计算平均值要容易得多。

 
 

销售移动总和 = VAR MaxDate = MAX( '日期'[日期] ) VAR MinDate = CALCULATE( MIN('日期'[日期]) , DATEADD( '日期'[日期], - 3, MONTH ) ) VAR DateRange = CALCULATETABLE( DATESBETWEEN( '日期'[日期] ,MinDate ,MaxDate ) ) VAR Result = CALCULATE([在线销售总和] ,DateRange ) RETURN 结果

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

其次,我使用DATEADD()来回移三个月。由于我包括了当前月份,因此我只回移了三个月。

如果我想排除当前月份,我必须采取不同的做法。在这种情况下,我必须获取第一个日期并回溯一天以获取上个月的最后一个日期(或使用EOMONTH(MAX('Date'[Date), -1) )。然后,使用 DATEADD() 回溯四个月)。

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

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

结果如下:

添加图片注释,不超过 140 字(可选)

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

 
 

VAR MaxDate = MAX( '日期'[日期] ) VAR MinDate = CALCULATE( MIN('日期'[日期]) , DATEADD( '日期'[日期], - 1, MONTH ) ) VAR Result = CALCULATE([在线销售额合计] ,'日期'[日期] >= MinDate && '日期'[日期] <= MaxDate ) 返回 结果

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

由于多种因素都会影响性能,我鼓励您在数据和用例中尝试这两种变体并检查差异。

让我们做平均值

现在,我终于开始计算平均值了。

我使用与在线销售额总计相同的逻辑,并使用 AVERAGEX() 来计算平均销售额:

 
 

平均在线销售额 = AVERAGEX('在线销售额' ,('在线销售额'[单价] * '在线销售额'[销售数量]) - '在线销售额'[折扣金额] )

接下来,我复制上面的度量来计算销售移动平均线,结果如下:

图 4 — 基本平均值和移动平均值的结果

我可以在这里结束并写下“任务完成”。但是别再说了。

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

因此,我开始编写度量值来测试它们。 我编写了以下度量值,将其用作分母,同时使用了 [在线销售额总和] 和提名人:

  • 统计在线销售量 = COUNTROWS('在线销售量')

  • 客户数量 = DISTINCTCOUNT('在线销售额'[CustomerKey])

  • 在线订单数量 = DISTINCTCOUNT('在线销售额'[SalesOrderNumber])

结果变量的代码如下(以 [Count Online Sales] 为例):

 
 

VAR 结果 = CALCULATE([在线销售总额] / [在线销售数量] ,日期范围 )

我可以想到更多的变体(例如,平均总体客户,甚至那些在这段时间内没有订单的客户)。但我决定就此打住,以免造成混淆。

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

图 5 — 所有变体的平均值结果

结果之间的差异非常大。

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

因此,我强烈建议您明确定义如何计算平均值。否则,您可能会向受众提供意想不到的甚至不正确的结果。

月平均销售额

计算平均值时还有一个差异:按月销售额的平均值。

让我们再次看一下月销售额的结果:

图 6 — 仅月销售额

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

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

(275'061'552.33 + 303'302'950.82 + 273'004'268.56 + 262'971'889.59) / 4 = ~278'585'165.3 (~ 因为舍入差异我们可能会得到略有不同的结果)

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

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

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

当我从每行的筛选上下文的角度来看待它时,我可以做得更好。

为什么不仅计算可视化中每行相关的月份的销售总额?

基于这种方法,我写了以下措施:

 
 

按月移动平均值 = // 1. 获取当前筛选上下文的第一个和最后一个日期 VAR MaxDate = MAX( 'Date'[Date] ) VAR MinDate = CALCULATE( MIN('Date'[Date]) , DATEADD( 'Date'[Date], - 3, MONTH ) ) // 2. 生成移动平均值所需的日期范围(四个月) VAR DateRange = CALCULATETABLE( DATESBETWEEN( 'Date'[Date] ,MinDate ,MaxDate ) ) // 3. 生成按步骤 2 生成的日期范围过滤的表格 // 此表仅包含四行 VAR SalesByMonth = CALCULATETABLE( SUMMARIZECOLUMNS( 'Date'[MonthKey] , "#Sales", [Sum Online Sales] ) ,DateRange ) RETURN // 4. 计算平均值步骤 3 中生成的表中的四个值 AVERAGEX(SalesByMonth, [#Sales])

这次,我添加了内嵌注释来解释那里发生的事情。

结果如下:

图 7 — 每月平均结果

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

如果您正在考虑创建一个每月预先计算的表格,请再考虑一下。

您将被迫添加对所有维度的引用,并增加数据的粒度,无论如何您都需要编写此度量来满足受众通过所有维度过滤数据的需求。

该解决方案非常高效,计算结果仅需不到0.4秒。

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

顺便说一句,这种方法也适用于计算平均值的平均值。

结论

平均值不等于平均值​​。我想这是很清楚的。

但更重要的是,了解应该计算什么以及如何计算至关重要。

理解为什么必须计算一个数字可以帮助你选择正确的计算逻辑。

当逻辑清晰时,应该定义编写 DAX 代码的方法。记住要从筛选上下文的角度来做。有时,这是违反直觉的,但它有助于开发高效的代码。

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

感谢关注雲闪世界。(Aws解决方案架构师vs开发人员&GCP解决方案架构师vs开发人员)

添加图片注释,不超过 140 字(可选)

相关文章:

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

在 DAX 中计算移动聚合很容易。但是&#xff0c;计算一段时间内的移动平均值时会有一些陷阱。由于其中一些陷阱是定义问题&#xff0c;因此我们必须小心&#xff0c;不要选择错误的方法。让我们看看细节。欢迎来到雲闪世界。 添加图片注释&#xff0c;不超过 140 字&#xff08…...

微信小程序 图片的上传

错误示范 /*从相册中选择文件 微信小程序*/chooseImage(){wx.chooseMedia({count: 9,mediaType: [image],sourceType: [album],success(res) {wx.request({url:"发送的端口占位符",data:res.tempFiles[0].tempFilePath,method:POST,success(res){//请求成功后应该返…...

软件测试人员发现更多程序bug

软件测试人员发现更多程序bug 1. 理解需求和业务&#xff0c;需求评审时候发现bug 熟悉了产品的业务流程、才能迅速找出软件中存在的一些重要的缺陷&#xff0c;发现的软件缺陷才是有价值的。否则即使你能找到一些软件缺陷&#xff0c;那也是纯软件的缺陷&#xff0c;价值不大…...

Nagle 算法:优化 TCP 网络中小数据包的传输

1. 前言 在网络通信中&#xff0c;TCP&#xff08;传输控制协议&#xff09;是最常用的协议之一&#xff0c;广泛应用于各种网络应用&#xff0c;如网页浏览、文件传输和在线游戏等。然而&#xff0c;随着互联网的普及&#xff0c;小数据包的频繁传输成为一个不容忽视的问题。…...

C#入门教程

目录 1.if分支语句 2.面向对象 3.static简单说明 1.if分支语句 我们的这个C#里面的if语句以及这个if-else语句和C语言里面没有区别&#xff0c;就是打这个输出上面的方式不一样&#xff0c;c#里面使用的是这个console.writeline这个指令&#xff0c;其他的这个判断逻辑都是一…...

【MySQL报错】---Data truncated for column ‘age‘ at row...

目录 一、前言二、问题分析三、解决办法 一、前言 欢迎大家来到权权的博客~欢迎大家对我的博客进行指导&#xff0c;有什么不对的地方&#xff0c;我会及时改进哦~ 博客主页链接点这里–>&#xff1a;权权的博客主页链接 二、问题分析 问题一修改表结构 XXX 为 not n…...

Go基础学习08-并发安全型类型-通道(chan)深入研究

文章目录 chan基础使用和理解通道模型&#xff1a;单通道、双通道双向通道单向通道单向通道的作用 缓冲通道和非缓冲通道数据发送和接收过程缓冲通道非缓冲通道 通道基本特性通道何时触发panicChannel和Select结合使用Select语句和通道的关系Select语句的分支选择规则有那些Sel…...

some 蓝桥杯题

12.反异或01串 - 蓝桥云课 (lanqiao.cn) #include "bits/stdc.h" #define int long long using namespace std; char c[10000000]; char s[10000000]; int cnt,Ans,mr,mid; int maxi; int p[10000000],pre[10000000]; signed main() {ios::sync_with_stdio(0);cin.t…...

[linux 驱动]input输入子系统详解与实战

目录 1 描述 2 结构体 2.1 input_class 2.2 input_dev 2.4 input_event 2.4 input_dev_type 3 input接口 3.1 input_allocate_device 3.2 input_free_device 3.3 input_register_device 3.4 input_unregister_device 3.5 input_event 3.6 input_sync 3.7 input_se…...

2023_Spark_实验十:Centos_Spark Local模式部署

参考这篇博客&#xff1a;【Centos8_配置单节点伪分布式Spark环境】_centos8伪分布式环境搭建-CSDN博客...

pyecharts-快速入门

pyecharts文档&#xff1a;渲染图表 - pyecharts - A Python Echarts Plotting Library built with love. pyecharts-gallery文档&#xff1a;中文简介 - Document (pyecharts.org) 一、快速入门案例 from pyecharts.charts import Barbar Bar() bar.add_xaxis(["衬衫…...

vue3打包疯狂报错

打包的时候报错很多Cannot find name ‘xxx‘ 。 但是npm run dev 是运行正常的。 解决方法&#xff1a;package.json中的vue-tsc --noEmit 删掉就可以了。 例如&#xff1a; 这是原来的 {"scripts": {"dev": "vite","build": &quo…...

STM32 软件触发ADC采集

0.91寸OLED屏幕大小的音频频谱&#xff0c;炫酷&#xff01; STM32另一个很少人知道的的功能——时钟监测 晶振与软件的关系&#xff08;深度理解&#xff09; STM32单片机一种另类的IO初始化方法 ADC是一个十分重要的功能&#xff0c;几乎任何一款单片机都会包含这个功能&a…...

Android SystemUI组件(08)睡眠灭屏 锁屏处理流程

该系列文章总纲链接&#xff1a;专题分纲目录 Android SystemUI组件 本章关键点总结 & 说明&#xff1a; 说明&#xff1a;本章节持续迭代之前章节的思维导图&#xff0c;主要关注左侧上方锁屏分析部分 睡眠灭屏 即可。 Power按键的处理逻辑最终是由PhoneWindowManager来完…...

C# 表达式与运算符

本课要点&#xff1a; 1、表达式的基本概念 2、常用的几种运算符 3、运算符的优先级 4、常见问题 一 表达式 表达式是由运算符和操作数组成的。、-、*和/等都是运算符&#xff0c;操作数包括文本、常量、变量和表达式等。 二 算术运算符 2.1 算术运算符的使用 三 常见错误 …...

SpringBoot--最大连接数和最大并发数

原文网址&#xff1a;SpringBoot--最大连接数和最大并发数-CSDN博客 简介 本文介绍SpringBoot的最大连接数和最大并发数。 配置 SpringBoot默认使用tomcat处理请求。tomcat可以指定连接数、线程数等配置。 server:tomcat:# 请求处理线程都在使用中时&#xff0c;新连接请求…...

CF687D Dividing Kingdom II 题解

Description 给定一个 n n n 个点、 m m m 条边的图&#xff0c;有 q q q 次询问&#xff0c;每次询问一个 [ l , r ] [l,r] [l,r] 的区间&#xff0c;求将 n n n 个点分为两个部分后&#xff0c;编号在 [ l , r ] [l,r] [l,r] 内的边中&#xff0c;两端点属于同一部分的…...

高空抛物AI检测算法:精准防控,技术革新守护城市安全

近年来&#xff0c;随着城市化进程的加速&#xff0c;高楼大厦如雨后春笋般涌现&#xff0c;但随之而来的高空抛物问题却成为城市管理的一大难题。高空抛物不仅严重威胁行人的安全&#xff0c;还可能引发法律纠纷和社会问题。为了有效预防和减少高空抛物事件的发生&#xff0c;…...

html+css+js实现Collapse 折叠面板

实现效果&#xff1a; HTML部分 <div class"collapse"><ul><li><div class"header"><h4>一致性 Consistency</h4><span class"iconfont icon-jiantou"></span></div><div class"…...

RM服务器研究(一)

客户端默认端口是10100&#xff1a; MultiPort.dll BOOL sub_10001070() { UINT v0; // esi BOOL result; // eax CHAR KeyName; // [espCh] [ebp-10Ch] DWORD flOldProtect; // [esp10h] [ebp-108h] CHAR Buffer; // [esp14h] [ebp-104h] char v5; // [esp15h] [e…...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器

——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的​​一体化测试平台​​&#xff0c;覆盖应用全生命周期测试需求&#xff0c;主要提供五大核心能力&#xff1a; ​​测试类型​​​​检测目标​​​​关键指标​​功能体验基…...

全球首个30米分辨率湿地数据集(2000—2022)

数据简介 今天我们分享的数据是全球30米分辨率湿地数据集&#xff0c;包含8种湿地亚类&#xff0c;该数据以0.5X0.5的瓦片存储&#xff0c;我们整理了所有属于中国的瓦片名称与其对应省份&#xff0c;方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放

简介 前面两期文章我们介绍了I2S的读取和写入&#xff0c;一个是通过INMP441麦克风模块采集音频&#xff0c;一个是通过PCM5102A模块播放音频&#xff0c;那如果我们将两者结合起来&#xff0c;将麦克风采集到的音频通过PCM5102A播放&#xff0c;是不是就可以做一个扩音器了呢…...

网站指纹识别

网站指纹识别 网站的最基本组成&#xff1a;服务器&#xff08;操作系统&#xff09;、中间件&#xff08;web容器&#xff09;、脚本语言、数据厍 为什么要了解这些&#xff1f;举个例子&#xff1a;发现了一个文件读取漏洞&#xff0c;我们需要读/etc/passwd&#xff0c;如…...

力扣热题100 k个一组反转链表题解

题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...

GitHub 趋势日报 (2025年06月06日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…...

Proxmox Mail Gateway安装指南:从零开始配置高效邮件过滤系统

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐&#xff1a;「storms…...

ubuntu系统文件误删(/lib/x86_64-linux-gnu/libc.so.6)修复方案 [成功解决]

报错信息&#xff1a;libc.so.6: cannot open shared object file: No such file or directory&#xff1a; #ls, ln, sudo...命令都不能用 error while loading shared libraries: libc.so.6: cannot open shared object file: No such file or directory重启后报错信息&…...

32单片机——基本定时器

STM32F103有众多的定时器&#xff0c;其中包括2个基本定时器&#xff08;TIM6和TIM7&#xff09;、4个通用定时器&#xff08;TIM2~TIM5&#xff09;、2个高级控制定时器&#xff08;TIM1和TIM8&#xff09;&#xff0c;这些定时器彼此完全独立&#xff0c;不共享任何资源 1、定…...