news 2026/3/21 14:19:19

在 Power BI 中处理预计算层次数据

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
在 Power BI 中处理预计算层次数据

原文:towardsdatascience.com/on-handling-precalculated-hierarchical-data-in-power-bi-4a215b96b99c?source=collection_archive---------12-----------------------#2024-05-03

虽然层次结构是数据中的常见概念,但一些来源以不寻常的格式提供数据。通常,我们在最低层级获取值。但当我们得到预先聚合的值时,会发生什么呢?在这里,我将深入探讨这个话题。

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

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

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

照片由ThisisEngineering提供,来源于Unsplash

介绍和数据

让我们设定一个场景:我们有一个包含行政费用的组织。

费用可以发生在国家、州和商店级别。

请看以下表格:

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

图 1 — 数据在预期位置的值(图源:作者)

我们看到两行分别是两家商店的费用,一行是南卡罗来纳州的组织费用。

我可以使用这些数据来计算费用的总和,并得出南卡罗来纳州所有商店的总费用。

但是,当源系统以不同的形式提供数据时,怎么办?

例如,像这样:

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

图 2 — 南卡罗来纳州预先聚合的值数据(图源:作者)

第三行包含了南卡罗来纳州两家商店的预先聚合的总和,以及南卡罗来纳州的组织费用。

简单地将这三行相加会得到错误的结果,因为结果中会重复计算这两家商店的费用:

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

图 3 — 聚合包含预先聚合值的数据时的错误结果(图源:作者)

挑战是:如何计算每个层级中的正确结果?

我的解决方案方法必须考虑以下几点:

但是我在哪里以及如何进行操作呢?

我有三种方法可以解决这个问题:

计算列

好的,让我们开始添加一些计算列。

首先,我需要知道每一行在层级中的级别。为此,我需要一个名为“路径长度”的列。这样的列通常用于处理父子层级。

因此,我添加了两列新列,以便更好地导航层级:

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

图 4 — 用于层级导航的额外计算列(作者提供的图)

我使用了以下表达式来计算 HierachyPath 列:

HierarchyPath='Cost Data'[Country]&IF('Cost Data'[State]<>'Cost Data'[Country],"|"&'Cost Data'[Country])&IF('Cost Data'[Store]<>'Cost Data'[State],"|"&'Cost Data'[Store])

然后,我使用了PATHLENGHTH()函数来计算“路径长度”列:

Path Length=PATHLENGTH('Cost Data'[HierarchyPath])

接下来,我可以编写一个表达式,执行以下步骤来处理表中的每一行:

  1. 获取当前职位的值。

  2. 获取当前职位在层级中下方的值的总和。

  3. 从第 2 步的总和中扣除当前行中的值。

结果是一个包含上面第一张图片中值的列。

Corrected Expenses=VAR CurrentExp='Cost Data'[Expenses]VAR CurrentLevel='Cost Data'[Path Length]VAR CurrentPath='Cost Data'[HierarchyPath]VAR ChildExpenses=CALCULATE(SUM('Cost Data'[Expenses]),REMOVEFILTERS('Cost Data'),'Cost Data'[Path Length]=CurrentLevel+1,CONTAINSSTRING('Cost Data'[HierarchyPath],CurrentPath))RETURN CurrentExp-ChildExpenses

关键在于“ChildExpenses”变量的表达式。该表达式计算了当前职位下、同一父级下的所有行的总和。

请注意,在 Power BI 中调用CALCULATE()函数计算一个计算列时,会触发上下文转换。

如果你不熟悉上下文转换的概念,确保阅读我解释它的文章:

## DAX 中上下文转换的精彩之处

行上下文和筛选上下文是 DAX 中的常见概念。但我们可以通过上下文转换在这两者之间切换。

towardsdatascience.com

这是该列的结果:

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

图 5 — 计算列的结果以获得正确的结果(作者提供的图)

这列替代了原始的 Expenses 列。

我将原始的 Expenses 列重命名为“Expense_Original”,并将计算列重命名为“Expenses”。由于 Expense_Original 列对报告没有用处,因此它在数据模型中是隐藏的。

现在,我可以直观地创建报告了:

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

图 6 — Power BI 中重命名的原始 Expenses 列和计算列并排显示(作者提供的图)

这是所需的结果。

但让我们看看我是否能创建一个度量值来计算正确的结果。

度量值

要编写一个度量值,我必须分别处理每个层级。

我不能使用与计算列相同的方法,因为在每个上层级(如国家或州)下,商店级别有多行数据。

结果是以下的 DAX 代码:

Expenses(Corrected)=VAR CurrentExp=[Expenses(Original)]VAR CurrentLevel=SELECTEDVALUE('Cost Data'[Path Length])VAR CurrentPath=SELECTEDVALUE('Cost Data'[HierarchyPath])VAR CurrentCountry=SELECTEDVALUE('Cost Data'[Country])VAR CurrentState=SELECTEDVALUE('Cost Data'[State])VAR CurrentStore=SELECTEDVALUE('Cost Data'[Store])VAR StateExpenses=--Get the pre-aggregated value of the Expensesforthe State CALCULATE([Expenses(Original)],REMOVEFILTERS('Cost Data'),'Cost Data'[Path Length]=CurrentLevel+1,CONTAINSSTRING('Cost Data'[HierarchyPath],CurrentPath))RETURN SWITCH(TRUE()--Calculation at the lowest level(Store)--But only when the Store has a different name than the State,NOT ISBLANK(CurrentStore)&&CurrentStore<>CurrentState,CurrentExp--Detract the Expensesfromthesumat the State level when the"Store"has the same nameasthe State--These are the rowswiththe Expensesforthe State,NOT ISBLANK(CurrentStore)&&CurrentStore=CurrentState,CurrentExp-StateExpenses--Calculate the Sum at the state level,NOT ISBLANK(CurrentState)&&ISBLANK(CurrentStore)--First,calculate the SumforallStores--But only when the Stores have a different name than the State,CALCULATE([Expenses(Original)],REMOVEFILTERS('Cost Data'),'Cost Data'[Country]=CurrentCountry,'Cost Data'[State]=CurrentState,'Cost Data'[Store]<>CurrentState)--At this stage,each rowinthe Visual has multiple Data rows.--Therefore,SELECTEDVALUE()forthe path doesn'treturnanyvalue.--Now add thesumforallStores,detracting the duplicate valueforthe"Stores"withthe same nameasthe State+(CALCULATE([Expenses(Original)],REMOVEFILTERS('Cost Data'),'Cost Data'[Country]=CurrentCountry,'Cost Data'[State]=CurrentState,'Cost Data'[Store]=CurrentState)-CALCULATE([Expenses(Original)],REMOVEFILTERS('Cost Data'),'Cost Data'[Country]=CurrentCountry,'Cost Data'[State]=CurrentState,'Cost Data'[Store]<>CurrentState))--Calculate the corrected Sumforthe Country--Must use the same logicasabove,but by moving one level above,considering only the Countryandthe State,CALCULATE([Expenses(Original)],REMOVEFILTERS('Cost Data'),'Cost Data'[Country]=CurrentCountry,'Cost Data'[State]<>CurrentCountry)+(CALCULATE([Expenses(Original)],REMOVEFILTERS('Cost Data'),'Cost Data'[Country]=CurrentCountry,'Cost Data'[State]=CurrentCountry)-CALCULATE([Expenses(Original)],REMOVEFILTERS('Cost Data'),'Cost Data'[Country]=CurrentCountry,'Cost Data'[State]<>CurrentCountry)))

我在代码中添加了大量的注释。

因此,我不会详细解释度量值的每一步。

然而,这种方法非常复杂,无法与使用计算列的方法的简便性相比。

可视化计算

最后,我可以使用 Power BI 中的最新功能之一:可视化计算。

可视化计算可以直接在视觉效果中添加计算,而无需将度量值添加到数据模型中。

这为我们提供了一些激动人心的可能性,并且消除了为满足特定视觉效果需求而编写度量值的必要。

我在下面的参考部分添加了一些关于这个话题的链接。

在这里,我尝试使用这个新功能来实现一个简单的解决方案。

然而,在进行了大量的研究和反复试验后,我仍然没有找到一个有效的解决方案。

我找到了解决方案来计算每个商店的正确结果,但对于州和国家的计算则没有成功:

Visual calculation=VAR CurrentCountry=[Country]VAR CurrentState=[State]RETURN SWITCH(TRUE(),[State]<>[Store]&&ISATLEVEL([Store]),[Expenses(Original)],[State]=[Store]&&ISATLEVEL([Store]),[Expenses(Original)]-CALCULATE(SUM([Expenses(Original)]),[State]<>[Store],[Country]=CurrentCountry,[State]=CurrentState))

这是这个公式的结果:

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

图 7 — 可视化计算的结果(图由作者提供)

我尝试找出计算州和国家结果的解决方案,但没有成功。

一个关键细节是,我们使用这种方法时不会得到总计。这可能是由于公式未完成的原因,但这是一个重要的细节。

尽管在这个特定场景中没有成功,我还是会将这个新功能纳入我的技能范围。

我鼓励你关注这个新的激动人心的功能。它为找到计算特定于某个视觉效果的结果提供了新的可能性,这些结果不会在其他地方重用。

Amit Chandak 写了关于这个话题的介绍:

[## 在 Power BI 中理解可视化计算:数据分析的革命

在 2024 年 2 月,Power BI 推出了一个正在预览中的具有颠覆性意义的功能:可视化计算。这个…

medium.com](https://medium.com/microsoft-power-bi/understanding-visual-calculations-in-power-bi-revolutionizing-data-analysis-1c15c943243e?source=post_page-----4a215b96b99c--------------------------------)

结论

当我开始写这篇文章时,我打算为你提供三个有效的解决方案来解决这个问题。

我找到了两种可行的解决方案。第一种是最直接且高效的,而第二种则是一个很好的操作层次结构的练习。

一段时间前,我写了一篇简短的文章,讲解了为什么预聚合数据对我们不利:

## Power BI 的预计算聚合—为什么你应该避免它们

我的一个客户总是希望在他的 Excel 文件中为报告预计算聚合。以下是我们应该避免的原因…

towardsdatascience.com

现在,我有一个更多的例子,证明我之前写的那句话是对的。

一个重要的收获是,准备和格式化数据以支持简易的解决方案至关重要,即使这意味着要额外付出努力去寻找解决方案。

参考文献

下面是一些关于新可视化计算功能的参考资料:

MS Power 博客上的可视化计算(预览)(2024 年 2 月)

使用可视化计算(预览)

SQLBI 文章页面(包含多个相关主题的文章,更多内容敬请期待)

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

Contoso 数据可以在 MIT 许可证下自由使用,具体请参见这里。

我提取了数据的一个子集,并进行了处理,以获得所需的数据。

请考虑关注我并订阅,以便在我添加新内容时立即收到电子邮件:

[## 每当 Salvatore Cagliari 发布新内容时,收到电子邮件通知。

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

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

我将我的文章免费开放给每个人,尽管 Medium 有付费墙。这允许我从每个读者那里赚取一点收入,但我关闭了付费墙,以便你能免费阅读我的文章。

你可以通过以下方式支持我的工作,这是我在空闲时间进行的工作:

buymeacoffee.com/salvatorecagliari

或扫描此二维码:

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

任何支持都非常感谢,这能帮助我腾出更多时间为你创造更多内容。

非常感谢。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/19 23:45:19

Switch大气层系统终极破解方案:零风险突破的6大核心模块全解析

Switch大气层系统终极破解方案&#xff1a;零风险突破的6大核心模块全解析 【免费下载链接】Atmosphere-stable 大气层整合包系统稳定版 项目地址: https://gitcode.com/gh_mirrors/at/Atmosphere-stable Switch破解、大气层系统与虚拟系统配置是每一位Switch玩家进阶的…

作者头像 李华
网站建设 2026/3/21 10:59:50

软件如何控制硬件:从开关到STM32寄存器位操作

1. 软件控制硬件的本质:从机械开关到寄存器位操作 在嵌入式系统开发的起点,几乎所有工程师都会遭遇一个看似朴素却直指核心的问题: 软件——这种无形的逻辑序列,如何精确地驱动物理世界中的晶体管、电阻、电容与LED? 这个问题的答案,并非藏于高级语言的语法糖之下,而…

作者头像 李华
网站建设 2026/3/17 22:32:57

TuxGuitar软件.gp文件打开故障排除指南

TuxGuitar软件.gp文件打开故障排除指南 【免费下载链接】tuxguitar Improve TuxGuitar and provide builds 项目地址: https://gitcode.com/gh_mirrors/tu/tuxguitar 识别问题现象 当用户尝试在Linux环境下使用TuxGuitar打开.gp格式吉他谱文件时&#xff0c;程序可能会…

作者头像 李华
网站建设 2026/3/14 13:07:10

AWPortrait-Z人像美化效果参数详解

AWPortrait-Z人像美化效果参数详解 想用AI给自己或朋友生成一张专业级的人像写真&#xff0c;但总觉得效果要么太假&#xff0c;要么不够自然&#xff1f;AWPortrait-Z这个工具你可能听说过&#xff0c;它基于强大的Z-Image模型&#xff0c;专门用来美化人像。但很多人打开它的…

作者头像 李华
网站建设 2026/3/14 14:31:47

RTX 4090优化!2.5D转真人引擎保姆级使用教程

RTX 4090优化&#xff01;2.5D转真人引擎保姆级使用教程 1. 这不是“又一个”转真人工具&#xff0c;而是专为RTX 4090量身定制的稳定方案 你是不是也试过那些标榜“一键转真人”的模型&#xff0c;结果刚上传一张19201080的二次元立绘&#xff0c;显存就直接爆红&#xff0c…

作者头像 李华