数据可视化之DAX篇(二)Power BI中的度量值和计算列,你搞清楚了吗?

摘要:
即使是已经学习了很长时间的人,对于计算列和度量值的写法也未必轻车熟路,还是有可能不明白其中到底有什么不同,这篇文章就试图把度量值和计算列彻底讲清楚。比如客户甲,有两笔订单,使用MAX计算出最大的订单日期,也就是甲的最后下单日期。通过这三种使用DAX的环境,以及上面的几个例子,应该能发现,无论是度量值、计算列还是建新表,其DAX代码本质上并没有什么不同,不同的只是下上文而已。

https://zhuanlan.zhihu.com/p/75462046

对于初学者,总是会把度量值和计算列搞混,我也经常碰到这样的问题,有些星友用文章中的代码总是报错,发给我一看,才知道TA把本来是度量值的DAX用在了计算列上,或者相反。

即使是已经学习了很长时间的人,对于计算列和度量值的写法也未必轻车熟路,还是有可能不明白其中到底有什么不同,这篇文章就试图把度量值和计算列彻底讲清楚。

什么是计算列、什么是度量值

计算列是直接在现有的表上添加一个新列,

数据可视化之DAX篇(二)Power BI中的度量值和计算列,你搞清楚了吗?第1张

新建的计算列,和表中之前已经存在的列一样,可以作为表格的行、列,图表的轴以及切片器的字段等等,也可以使用计算列与其他表建立关系。

度量值,如果不放到上下文环境中,它就是一个孤立的公式,并没有视觉上的计算结果,因此,很多人会觉得度量值比较难以理解,尤其是Excel用习惯的人,都会倾向于使用计算列。

字段标识不同

如下图的字段面板

数据可视化之DAX篇(二)Power BI中的度量值和计算列,你搞清楚了吗?第2张

倒数第二个字段,前面有fx符号,代表的是计算列;而最下面一个,前面是个计算器的标识,表明[最后订单日期]是一个度量值。

怎么写计算列、怎么写度量值?

这个才是大家更关注的问题,也是平时容易出错的地方。下面以一个实例来介绍计算列与度量值的写法有什么不同。

以这个简化的订单表为例,如何计算出每个客户的最后下单时间?

数据可视化之DAX篇(二)Power BI中的度量值和计算列,你搞清楚了吗?第3张

计算列的写法

不少人也许直接这样写,

数据可视化之DAX篇(二)Power BI中的度量值和计算列,你搞清楚了吗?第4张

结果都是订单表中最后一个订单日期,显然与我们的期望不符,为什么会这样呢?

计算列的上下文就是当前行,但是MAX函数(包括SUM、MIN等聚合函数)并不能将行上下文转化为筛选上下文,也就是说当前行没有起到筛选作用,它就会返回整个表的最大订单日期。

关于上下文,不要理解的太复杂,完全可以按中文字面意思来理解,简单来说就是当前的计算环境,一般分为行上下文和筛选上下文,行上下文可以简单的理解为当前行,行上下文并不会必选产生筛选作用,只有筛选上下文才会产生筛选作用,筛选上下文有很多种形式,比如表格的当前行,矩阵的行和列、图表的坐标轴、报表的切片器、筛选器等。

如何让当前行发生筛选作用呢?在MAX函数外围再套个CALCULATE函数就可以了,

数据可视化之DAX篇(二)Power BI中的度量值和计算列,你搞清楚了吗?第5张

这样返回的下单日期都不同了,但是仔细看就会发现,返回的日期和当前行的下单日期是一样的,并没有按照客户进行计算。

再强调一遍,计算列的上下文就是当前行,包括当前行的每一个值,在上表中,每一行的数据是唯一的,因此只能返回当前行的订单日期。

那么到底如何按照客户来计算,返回当前客户的最后下单日期呢?

解决这个问题的DAX写法有很多种,这里用个相对简洁的代码,

数据可视化之DAX篇(二)Power BI中的度量值和计算列,你搞清楚了吗?第6张

ALLEXCEPT函数的意思是,清除订单表其他列的筛选作用,只保留客户列的筛选,这样当前行的上下文,其他列的筛选作用清除了,只有客户发生筛选作用。

比如客户甲,有两笔订单,使用MAX计算出最大的订单日期,也就是甲的最后下单日期。

上面说了这么多计算列的写法,那么度量值该怎么写呢?

最后下单日期=MAX('订单表'[订单日期])

是不是简单到不敢相信,那么如何看到计算结果呢,最简便的方式就是直接用个表格或者矩阵展现结果,

再举个例子,依然是这个订单表,如何计算每个产品的最后卖出日期?

如果你理解了上面计算列的原理,这个问题是不是也很容易就出来了,

数据可视化之DAX篇(二)Power BI中的度量值和计算列,你搞清楚了吗?第7张

那么度量值又是如何写才能解决这个问题的呢?

其实度量值的写法可以完全不变,依然可以用上面的代码(MAX('订单表'[订单日期]),只要把表格的维度改为产品名称就可以了,

数据可视化之DAX篇(二)Power BI中的度量值和计算列,你搞清楚了吗?第8张

通过上面两个问题,你看出来计算列和度量值有哪里不同了吗?

在计算列中,其上下文是明确的,就是当前行,并且可以根据需要缩小为当前行的某一列;

而度量值,编写时并没有明确的上下文,度量值写好之后,可以放在任意的上下文环境中,执行不同的计算;

计算列写好代码,数据自动计算出来,并且不受外部筛选器的影响;

而度量值写好之后,并没有立即计算,只有放到上下文中时,才进行计算并返回结果。

所以利用DAX解决问题时,首先应想到上下文是什么,新建列时如何利用当前行的上下文?

而度量值虽然暂时没有上下文,但在建度量值之前,也首先应该想清楚,我需要构建怎样的上下文环境才能得到期望的结果,然后利用心中所想的上下文环境,来对应的编写度量值的DAX代码。

在PowerBI中,除了计算列和度量值,还有个地方可以用到DAX,就是使用DAX新建表,

数据可视化之DAX篇(二)Power BI中的度量值和计算列,你搞清楚了吗?第9张

使用建表的方式同时可以解决上面的问题,

数据可视化之DAX篇(二)Power BI中的度量值和计算列,你搞清楚了吗?第10张

其中VALUES('订单表'[客户]),返回客户的不重复列表,就是为了给后面的代码提供上下文,有了这个上下文,后面的代码与新建列的写法是一样的。

通过这三种使用DAX的环境,以及上面的几个例子,应该能发现,无论是度量值、计算列还是建新表,其DAX代码本质上并没有什么不同,不同的只是下上文而已。

计算列只能利用当前行上下文;新建表可以使用DAX构建上下文;’而度量值最灵活,先不管上下文,写好代码之后,给什么上下文,就执行什么运算,或者说需要什么计算,就给度量值提供什么上下文。

你以后再遇到问题打算用DAX实现,一定要先想清楚,是通过计算列、新表还是度量值来解决,然后再开始写对应的DAX。

计算列和度量值写法的不同点

关于计算列和度量值在写法上有一些不同,比如在计算列中使用列,可以直接使用,默认就是该列的当前行,比如返回当前订单日期的前一天,可以直接写:

数据可视化之DAX篇(二)Power BI中的度量值和计算列,你搞清楚了吗?第11张

而在度量值中使用列,必须在列上套一个聚合函数,否则不能自动转换为筛选上下文,计算订单日期前一天的度量值应该这样写:

订单日期前一天 = MAX('订单表'[订单日期])-1

数据可视化之DAX篇(二)Power BI中的度量值和计算列,你搞清楚了吗?第12张

什么时候使用新建列,什么时候使用度量值

一般来说,为了性能考虑,能用度量值解决的问题就尽量不用计算列(参考:高效使用Power BI的15条建议)。只有当你需要利用新建的计算列生成切片器(度量值不能用于切片器),或者需要用这个字段与其他表建立关系时,才需要新建列。

另外当需要创建很复杂的字段时,尽量使用计算列,因为它需要时间来运算,提前运算完成,而不是在需要用的时候再进行计算(度量值是用的时候才计算),可以带来更流畅的体验。

总结

计算列和度量值在DAX代码的写法上并没有本质不同,形式上的不同只是由于上下文环境的区别引起的。

二者的本质不同在于其运算特点,是否根据上下文动态运算、以及计算时间上的不同,才是根本的差异。

如果你看到这里还是有不明白的地方,那么从头再仔细看一遍吧。

免责声明:文章转载自《数据可视化之DAX篇(二)Power BI中的度量值和计算列,你搞清楚了吗?》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇[windows]命令行关机或重启电脑CentOS查看CPU、内存、网络流量和磁盘 I/O【详细】下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Core Animation 文档翻译 (第二篇)—核心动画基础要素

前言 核心动画为我们APP内Views动画和其他可视化元素动画提供了综合性的实现体系。核心动画不是我们APP内Views的替代品,相反,它是一种结合Views来提供更好性能和支持Content动画的技术。它通过将Views的Content缓存进可以被绘图软件直接操作处理的Bitmaps来达到这种高性能。在某些情况下,这种缓存技术可能需要我们重新思考我们将...

.NET Core授权失败如何自定义响应信息?

前言 在.NET 5之前,当授权失败即403时无法很友好的自定义错误信息,以致于比如利用Vue获取到的是空响应,不能很好的处理实际业务,同时涉及到权限粒度控制到控制器、Action,也不能很好的获取对应路由信息。本文我们来看看在.NET 5中为何要出现针对授权失败的中间件接口?它是如何一步步衍生出来的呢?以及对于授权失败根据实际需要如何自定义响应错误,以及...

EFCore梳理

一、CodeFirst模式 官网:https://docs.microsoft.com/zh-cn/ef/core/get-started/overview/first-app?tabs=visual-studio 下面进行一个简单的示例。 代码:https://github.com/qiuxianhu/EFCoreSummary 1、创建一个.NETCo...

Quartz-2D绘图之图形上下文详解

  上一篇文章大概描述了下Quartz里面大体所包含的东西,但是对具体的细节实现以及如何调用相应API却没有讲。这篇文章就先讲讲图形上下文(Graphics Context)的具体操作。   所谓Graphics Context,其实就是表示了一个绘制目标,也就是你打算绘制的地方,它包含绘制系统用于完成绘制指令的绘制参数和设备相关信息。Graphics C...

kubernetes配置(kubeconfig)对多集群的访问

配置对多集群的访问 本文展示如何使用配置文件来配置对多个集群的访问。 在将集群、用户和上下文定义在一个或多个配置文件中之后,用户可以使用kubectl config use-context命令快速地在集群之间进行切换。 注意:用于配置集群访问的文件有时被称为kubeconfig 文件。 这是一种引用配置文件的通用方式,并不意味着存在一个名为kubecon...

tsne降维可视化

Python代码:准备训练样本的数据和标签:train_X4000.txt、train_y4000.txt 放于tsne.py当前目录.(具体t-SNE – Laurens van der Maaten http://lvdmaaten.github.io/tsne/,Python implementation), tsne.py代码:(为了使得figu...