当前位置: 首页 > 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…...

云岚到家xxl job 配置

调度中心&#xff1a; 负责管理调度信息&#xff0c;按照调度配置发出调度请求&#xff0c;自身不承担业务代码&#xff1b; 主要职责为执行器管理、任务管理、监控运维、日志管理等 任务执行器&#xff1a; 负责接收调度请求并执行任务逻辑&#xff1b; 主要职责是执行任…...

国内动态短效sk5

HTTP爬虫代理,软件测试&#xff0c; 动态转发IP方案&#xff0c;全高匿名&#xff0c;私密IP&#xff0c;固定网关将您每次请求的HTTP重定向到不同的后端IP&#xff0c;支持API;指路小熊IP https://www.xiaoxiongip.com?fromqkJWgD可测...

【路径规划】路径平滑算法,A星算法拐点的圆弧化处理

摘要 A算法广泛应用于路径规划中&#xff0c;但其生成的路径通常在拐点处呈现不平滑的折线。为了提升路径的平滑性&#xff0c;本文提出了一种基于圆弧的平滑处理方法&#xff0c;用于对A算法产生的路径拐点进行优化。通过在MATLAB中进行仿真验证&#xff0c;该方法能够有效减…...

【寻找one piece的算法之路】——双指针算法!他与她是否会相遇呢?

&#x1f490;个人主页&#xff1a;初晴~ &#x1f4da;相关专栏&#xff1a;寻找one piece的刷题之路 什么是双指针算法 双指针算法是一种常用的编程技巧&#xff0c;尤其在处理数组和字符串问题时非常有效。这种方法的核心思想是使用两个指针来遍历数据结构&#xff0c;这两…...

UFS 3.1架构简介

整个UFS协议栈可以分为三层:应用层(UFS Application Layer(UAP)),传输层(UFS Transport Layer(UTP)),链路层(UIC InterConnect Layer(UIC))。应用层发出SCSI命令(UFS没有自己的命令使用的是简化的SCSI命令),在传输层将SCSI分装为UPIU,再经过链路层将命令发送给Devices。下…...

注册安全分析报告:科研诚信查询平台无验证方式导致安全隐患

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 1. 暴力破解密码&#xff0c;造成用户信息泄露 2. 短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉 3. 带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造…...

04.useTitle

在 React 应用中,动态更新页面标题是提升用户体验的一个重要方面。它可以让用户更清楚地知道当前页面的内容或状态,特别是在单页应用(SPA)中。useTitle 钩子提供了一种简单而有效的方式来管理文档标题。以下是如何实现和使用这个自定义钩子: const useTitle = title =>…...

ROS2中的srv、action、发布订阅三种方式

ROS2中的srv、action、发布订阅三种方式 以下是ROS2中srv、action、发布订阅三种方式的差异和使用场景的表格形式呈现&#xff1a; 特性/方式srv&#xff08;服务&#xff09;action&#xff08;动作&#xff09;发布订阅&#xff08;Publish-Subscribe&#xff09;通信模式请…...

HarmonyOS/OpenHarmony 自定义弹窗页面级层级控制解决方案

关键词&#xff1a;CuntomDialog自定义弹窗、SubWindow子窗口、页面级、弹窗层级控制、鸿蒙、弹窗展示层级异常 问题存在API版本&#xff1a;API10 - API12&#xff08;该问题已反馈&#xff0c;期望后续官方能增加页面级控制能力&#xff09; 在正常的鸿蒙app开发过程中&…...

C/C++进阶(一)--内存管理

更多精彩内容..... &#x1f389;❤️播主の主页✨&#x1f618; Stark、-CSDN博客 本文所在专栏&#xff1a; 学习专栏C语言_Stark、的博客-CSDN博客 其它专栏&#xff1a; 数据结构与算法_Stark、的博客-CSDN博客 ​​​​​​项目实战C系列_Stark、的博客-CSDN博客 座右铭&a…...