数据获取
数据清洗
对导入的数据进行数据整理的过程一般称为「数据清洗」,之所以称之为清洗,是因为在数据分析师眼中,杂乱的数据就是脏数据,只有被清洗成干净的数据后才可以进行分析使用。这些都是在原表数据基础上的分分合合。
数据丰富
做数据分析的时候还经常需要在原有数据的基础上增加一些辅助数据,比如加入新列、新行,或者从其他表中添加进来更多维度的数据,这些就是数据丰富的过程。
M函数
- 在 PQ 中用的函数称之为 M 函数。
- 在之前的 PQ 操作中,其实 M 函数无处不在,比如做数据清洗的每一个步骤,背后都有 M函数的影子。打开高级编辑器,可以看到所有这些步骤的 M 语言。
- 如果我们不进行鼠标操作,直接在编辑器中编写这些语言,也是可以得到最终的结果的,有了 M 函数,PQ 的数据处理具有很强的可读性和可移植性。
- 常用的函数,比如文本函数、字符串函数、日期函数等
M 函数基本规范
⚫ M 函数对大小写敏感,每一个字母必须按函数规范书写,第一个字母都是大写
⚫ 表被称为 Table,每行的内容是一个 Record,每列的内容是一个 List
⚫ 行标用大括号{ },比如取第一行的内容:=表{0} //PQ 的第一行从 0 开始
⚫ 列标用中括号[ ],比如取自定义列的内容:=表[自定义]
⚫ 取第一行自定义列的内容:=表{0}[自定义]
常用的 M 函数
聚合函数:
求和:List.Sum()
求最小值:List.Min()
求最大值:List.Max()
求平均值:List.Average()
文本函数:
求文本长度:Text.Length()
去文本空格:Text.Trim()
取前 n 个字符:Text.Start(文本,n)
取后 n 个字符:Text.End(文本,n)
提取数据函数:
从 Excel 表中提取数据:Excel.Workbook()
从 Csv/Txt 中提取数据:Csv.Document()
条件函数:
if else then (相当于 Excel 中的 IF)
从哪里查找 M 函数
新建一个空查询,在公式标记栏中输入= #shared
,就把所有的 M 函数显示出来了,点击某
个函数,最下方便出现该函数的注释
使用
原文
Power Query M 公式语言查询由创建混合查询的公式表达式步骤组成。可以计算公式表达式,从而生成一个值。
- let 表达式封装了一组要计算的值,为其分配名称,
- 然后在 in 语句后面的后续表达式中使用。
例如,let 表达式可以包含一个 Source 变量,该变量等于 Text.Proper() 的值,并在适当的大小写中生成文本值。
let表达式:
let
Source = Text.Proper(“hello world”)
in
Source
在上面的示例中,Text.Proper(“hello world”) 的计算结果为 “Hello World”。
原始值
函数值
函数是一个值,当使用参数调用时,它会生成一个新值。
函数的编写方法是在括号中列出函数的参数,后跟转到符号 =>
,后跟定义函数的表达式。
例如,若要创建名为“MyFunction”的函数,该函数具有两个参数,并对 parameter1 和 parameter2 执行计算:
let
MyFunction = (parameter1, parameter2) => (parameter1 + parameter2) / 2
in
MyFunction
调用 MyFunction() 将返回结果:
let
Source = MyFunction(2, 4)
in
Source
此代码生成值 3。
结构化数据值
结构化数据可以包含任意 M 值
M 语言支持以下结构化数据值:
1. | List
Power Query M 支持无限列表大小,但如果列表以文本形式写入,则列表具有固定长度。例如,{1, 2, 3} 的固定长度为 3。
以下是一些 List 示例。
2. | Record
3. | Table
4. | Additional structured data examples
数据建模
-
PowerBI 中的核心概念:度量值,据建模语言:DAX。
-
Power BI可以从多个表格、多种来源的数据中,根据不同的维度、不同的逻辑来聚合分析数据;而提取数据的前提是要将这些数据表建立关系,这个建立关系的过程就是数据建模。
-
表格导入后,PowerBI 会自动检测关系并联接,没有检测到的表,可以点击一个表中的字段托到另一个表的对应字
段上,就可以建立关系了。
- 点击关系连接线,两边的表对应的连接字段会框选,双击关系线,进入编辑关系窗口:
- 编辑关系窗口可以看出关联的两个表和对应的字段,也可以更改联结的字段;下面还有两
个可选项,基数和交叉筛选方向。
1.基数
⚫ 基数就是两个连接字段的对应关系,分为多对一、一对一和一对多,一对多和多对一
其实是一样的,实际上就是两种关系:
⚫ 多对一(*:1):这是最常见的类型,代表一个表中的关系列有重复值,而在另一个表
中是单一值
⚫ 一对一(1:1):两个表是一对一的关系,列中的每个值在两个表中都是唯一的
⚫ 具有唯一值的表通常称为“查找表”
,而具有多个值的表称为“引用表”
。在上述的关系图
上,产品明细表上类别手机、平板、电脑都不是唯一的,每个品牌都有这种类型,是
个引用表;但类别表上,几种类别都是唯一值,因此这两个表是多对一的关系,类别
表也就是查找表。
2.交叉筛选方向
表示数据筛选的流向,有两种类型:
⚫ 双向:两个表可以互相筛选
⚫ 单向:一个表只能对另一个表筛选,而不能反向
这个稍微有点抽象,以后可以根据实例来理解。
使用:
根据刚才建立的数据模型,可以做一下分析,比如统计各品牌产品的销售额:
在销售明细表中并不能直接统计出按品牌的销售额,可以先建一个度量值,在建模选项卡下,点击新建度量值,公式栏输入:销售额 = sum(‘销售明细表’[金额])然后[销售额]这个度量值就建立了,在右边字段区可以看到。
为了在画布上直观的看到各品牌销售额,在可视化里添加“卡片图”,把度量值字段放进去,可以看到卡片图的数字出来了,
这个数字是整体销售金额,因为还没有做任何筛选,为了看出各品牌的销售金额,现在添加一个品牌的切片器
点击不同的品牌,数值跟着变化,通过这个例子,可以看出:
⚫ 展现的数字并不是一个表得出的,根据之前建立的关系模型,销售明细表中的数据被品牌表中的[品牌名称]字段所筛选,展现出来不同品牌的销售额,这就是数据模型的威力。
⚫ 品牌销售额是通过[销售额]这个度量值,加入到卡片图中,并可与切片器交互,展现不同的数据。
- 通过这个实例,还看到了以前从未见过的的概念:度量值,这可以说是 PowerBI 数据建模的灵魂,创建度量值的公式称为 DAX 公式(看起来和 Excel 公式非常相似),刚才创建的这个度量值只是一个简单的 sum 函数,并没有任何的过滤条件,但是却可以根据切片器的筛选而展现不同的数值,所以度量值被称为移动的公式,这里只是简单介绍,有个印象即
可。 - 学习数据建模的更多知识,可以说都是依据度量值的逻辑以及建立度量值的 DAX 公式来展开,是下一步学习 Power BI 的重点
度量值
度量值是用 DAX 公式创建一个虚拟字段的数据值,她不改变源数据,也不改变数据模型,如果你不在报表上使用她,甚至不知道她是什么样子的,而一旦被拖拽到报表上,便发挥巨大的作用,她可以随着切片器的筛选而闪转腾挪、变化万端,所以度量值一般在报表交互时使用。
- 度量值的最重要的特征:上下文
- 上下文就是度量值所处的环境,筛选表的行列标签、切片器的选中,都是度量值的上下文
- 度量值的运算依赖上下文,上下文又分为外部上下文和内部上下文,外部上下文就是外部可以看得见的筛选:标签和切片器,而内部上下文就是创建度量值的 DAX 公式,它的查询筛选函数可以扩大、限制或者重置外部上下文。利用外部上下文和 DAX 的有效配合,度量值的灵活性大大增强,可以筛选出真正需要的数据集合并执行聚合运算。如果说度量值是 Power BI 数据建模的灵魂,那么 DAX 就是度量值的灵魂。
- 比如北京 2017 年截至 5 月的苹果手机累计销售额 3424000,它的上下文就是下面这 5个维度:
理解了上下文,就理解了度量值的最重要的特征,因此她被称为移动的公式,随着上下文环境的不同而展示不同的数据,度量值另外还有两个主要特征:
⚫ 度量值不浪费内存,只有被拖到图表上才执行运算,如果数据量非常大的时候这点非
常有利
⚫ 度量值可以循环使用,比如上面的建立的度量值:
本年累计销售额 = TOTALYTD([销售总额],‘日期表’[日期])
累计同比增长率 = divide([本年累计销售额],[上年累计销售额])-1,- 就是直接调用之前建立好的度量值,所以以后在模型中新建度量值的时候,推荐从最简单的度量值开始建。
- 度量值的创建离不开函数,这里用到的函数称为 DAX
DAX
- DAX 是英文 Data Analysis Expression 的缩写,意思是数据分析表达式,从名称上就可以看出,DAX 公式是用作数据分析的,事实上也确实如此。
- 数据分析就是从茫茫数据中提取有用的信息,执行一定的运算,形成结论的过程,而 DAX的主要功能正是查询和运算,DAX 查询函数负责筛选出有用的数据集合,然后利用 DAX 的聚合函数执行计算。
- 度量值的运算依赖上下文,上下文又分为外部上下文和内部上下文,外部上下文就是外部可以看得见的筛选:标签和切片器,而内部上下文就是创建度量值的 DAX 公式,它的查询筛选函数可以扩大、限制或者重置外部上下文。利用外部上下文和 DAX 的有效配合,度量值的灵活性大大增强,可以筛选出真正需要的数据集合并执行聚合运算。如果说度量值是 Power BI 数据建模的灵魂,那么 DAX 就是度量值的灵魂。
- DAX 可以在 Power BI Desktop 的数据建模和 Power Pivot 中使用,除了可以创建度量值,还可以新建列,比如想把这个日期表上的月用两位数字表示,即 7 月用 07 表示,新建列 然后编辑栏输入:
月份 = format(‘日期表’[日期],“MM”)
然后就增加了一列[月份],
不过除非特别有必要,不建议用新建列的方式做数据丰富,这样更占用内存,如果想增加一列,可以在源数据上,回到查询编辑器里面增加一列然后上载到数据模型中使用。
DAX 参数的基本格式
⚫ 表名用单引号' '
括着
‘日期表’
⚫ 字段用中括号[ ]
括着
[日期]
⚫ 度量值也是用中括号[ ]
⚫ 引用字段始终要包含表名,以和度量值区分开
DAX 常用函数
聚合函数
⚫ SUM
⚫ AVERAGE
⚫ MIN
⚫ MAX
这几个函数的使用和在 Excel 中完全一致,DAX 中还有一类特有的函数非常有用,和这几个函数很像,后面加个 X,
⚫ SUMX
⚫ AVERAGEX
⚫ MINX
⚫ MAXX
⚫ RANKX
这几个函数可以循环访问表的每一行,并执行计算,所以也被称为迭代函数。
其他常见的聚合函数:
⚫ COUNT:计数
⚫ COUNTROWS:计算行数
⚫ DISTINCTCOUNT:计算不重复值的个数
时间智能函数
⚫ PREVIOUSYEAR/Q/M/D:上一年/季/月/日
⚫ NEXTYEAR/Q/M/D:下一年/季/月/日
⚫ TOTALYTD/QTD/MTD:年/季/月初至今
⚫ SAMEPERIODLASTYEAR:上年同期
⚫ PARALLELPERIOD:上一期
⚫ DATESINPERIOD:指定期间的日期
关于时间智能函数,利用它可以灵活的筛选出一段我们需要的时间区间,做同比、环比、滚动预测、移动平均等数据分析时,都会用到这类函数。
筛选函数
⚫ FILTER:筛选
⚫ ALL:所有值,可以清除筛选
⚫ ALLEXCEPT:保留指定列
⚫ VALUES:返回不重复值
这几个函数,就是典型的 DAX 查询函数,通过筛选来操纵上下文的范围。
最后放出 DAX 最重要也是最常用的函数:CALCULATE
,这个函数简直就是 DAX 本身,学好
这个函数就基本上掌握了 DAX
常用的 DAX 函数
CALCULATE
- PowerBI 中最重要的函数
CALCULATE
语法:
CALCULATE(<expression>,<filter1>,<filter2>…)
⚫ 第一个参数是计算表达式,可以执行各种聚合运算
⚫ 从第二个参数开始,是一系列筛选条件,可以为空;如果多个筛选条件,用逗号分隔。 所有筛选条件的交集形成最终的筛选数据集合
⚫ 根据筛选出的数据集合执行第一个参数的聚合运算并返回运算结果
前文提到 DAX 函数可以更改外部上下文,现在通过实例来理解 DAX 中最精髓的函数CALCULATE 的计算原理,并看看它是如何更改外部上下文的。
CALCULATE 应用实例
导入下面这个产品明细表:
新建一个度量值求每种产品的数量:
产品数量 = COUNTROWS('产品明细')
因为每种产品的只有 1 行,所以求产品明细表的行数就相当于求各种产品的数量,把产品名称和该度量值拖拽入矩阵表
这里外部上下文就是表格每行的行标签。
01 | 筛选条件为空,不影响外部上下文
现在开始用 CALCULATE 函数创建一个度量值:
产品数量 1 = CALCULATE([产品数量])
只是用了第一个参数,筛选条件为空,因为没有内部筛选所以完全依赖外部上下文,出来的结果也和原度量值一致。
另外,介绍 CALCULATE 语法的时候说,第一个参数为聚合运算表达式,为什么这里没有
用聚合函数而只用了一个度量值呢?这是因为 度量值[产品数量] 本身就是一个聚合函数运
算,实际上 度量值[产品数量 1] 等同于这个:
产品数量 1 = CALCULATE(COUNTROWS('产品明细'))
DAX 函数可以直接引用已经创建好的度量值,可以使 DAX 函数看起来更简洁、更具可读
性,这也是建议从最简单的度量值开始建的原因。
02 | 添加限制条件,缩小上下文
建一个度量值[产品数量 2],
产品数量 2 = CALCULATE([产品数量],'产品明细'[品牌]="苹果")
发现只有苹果的产品计数显示出来,而其他品牌的数据没有了,这是因为 CALCULATE 的第二个参数的限制,只筛选品牌为“苹果”的,限制了外部的上下文,非苹果的产品都不再运算。
03 | 结合 ALL 函数,扩大上下文
新建度量值[产品数量 3],
产品数量 3 = CALCULATE([产品数量],ALL('产品明细'))
这次的数据居然是所有产品的数量,这是因为筛选条件使用了 ALL 函数,ALL(‘产品明细’)
的意思是清除产品明细表里的所有筛选,外部筛选器不起作用了,每行统计的都是该表中
的所有产品。
每行的数据都是 9,你可能觉得这个 ALL 函数没什么用,运算的数据没有什么意义,会误
导人,实际上当然不是这样,这个数据使用的地方非常多,比如我们想计算每个产品数量
占总产品数量的比重,直接写个度量值:
产品占比=[产品数量]/[产品数量 3]
产品占比就计算出来了,这就是统计总数的一个功能。
04 | 重置上下文
新建度量值[产品数量 4],
产品数量 4 = CALCULATE([产品数量], all('产品明细'[产品名称]), '产品明细'[类别]="手机")
先用 ALL 函数清除外部上下文,然后又新增了一个筛选条件,类别为"手机"的产品数量,
那么结果会是什么样的呢,
- 每一行产品的数量都是 3,正好符合建立这个度量值的逻辑,被 ALL 清除行标签的外部筛选后,从全部产品中统计品类为"手机"的产品的数量,所以每行都返回 3.
- 通过以上几个简单的例子,可以领会到 CALCULATE 的计算逻辑,通过从第二个参数开始的筛选条件,得到一个数据集合,并利用第一个参数执行聚合运算,这不就是 DAX 要实现的功能:提取有用数据并执行聚合运算吗,所以说 CALCULATE 几乎就是 DAX 本身,它就是实现 DAX 功能的引擎,并能灵活的操控外部上下文,后面的数据分析也都离不开CALCULATE 的身影。
FILTER 函数
- CALCULATE 函数的第二个及之后的参数是筛选条件,而 FILTER 函数正是为筛选而生。
FILTER 语法
FILTER(<table>,<filter>)
⚫ 第一个参数<table>
是要筛选的表
⚫ 第二个参数<filter>
是筛选条件
⚫ 返回的是一张表,不能单独使用,需要与其他函数结合使用
FILTER 应用
前一篇文章中介绍 CALCULATE 的时候,没有使用 FILTER 函数也实现了筛选,你可能会问,既然不用 FILTER 函数也可以,为什么还要使用 FILTER 呢?
那是因为前文中的筛选条件都是最简单的筛选,没有必要使用强大的 FILTER,其实用FILTER 也是可以实现的,比如这个 度量值[产品数量 2]
= CALCULATE([产品数量],'产品明细'[品牌]="苹果")
等同于:
= CALCULATE([产品数量], FILTER(ALL('产品明细'[品牌]), '产品明细'[品牌]="苹果"))
这两种方式返回的结果完全一致。
- 在这个简单的例子里看起来好像用 FILTER 写起来更复杂,不用 FILTER 的情况下显得更简
洁,但是如果我们要做更复杂的运算,通过简单的布尔表达式根本无法实现,必须借助
FILTER。
例子
找出年销售额超过 2000 万的城市销售金额
第一个度量值还是之间建好的,
销售总额 = sum('销售明细'[销售额])
再建一个度量值[大于 2000 万的城市销售金额],
= CALCULATE([销售总额], FILTER(ALL('门店城市'), [销售总额]>20000000))
这个度量值先利用 FILTER 函数,筛选出销售大于 2000 万的城市有哪几个,然后再汇总这些城市的销售额,返回结果如下,
超过 2000 万销售额的城市的销售额总计等于 451026000,但发现上面明细的两个数字之和并不等于总计,这正是 PowerBI 中数据模型的特点,在这个表格中,每个数据都是独立运算的,和其他数字没有关系。
上面两个数字代表的是,在销售额超过 2000 万的城市中,单个产品的销售额也大于 2000万的只有苹果电脑和苹果手机。
为什么会有产品的销售额也大于 2000 万这个筛选条件呢,不要忘了还有外部的筛选上下文,在这个表中即是行标签,这两个数字正是内部上下文和外部上下文相结合,筛选计算的结果。
这就是 FILTER 的一个简单应用,这里要特别记住这个函数嵌套组合,
CALCULATE(…,FILTER(ALL(…),…))
做各种分析时会经常用到这个组合。
HASONEVALUE 和 SUMX 函数
上一篇文章最后留了个问题,就是计算大于 2000 万的城市销售额时,总计金额不等于明细之和,看起来比较奇怪,
其实总计和上面的这两个数字都有自己的逻辑,分别代表不同的上下文环境中的销售额,按照常规的汇总逻辑来理解二者关系是没有意义的。但是为了避免误导,有时还是需要避免出现这种状况,这里有两个解决的思路,
HASONEVALUE
是个逻辑判断函数,如果有单一值,返回 ture,否则返回 false,具体语法
如下:
HASONEVALUE(<columnName>)
参数只有一个:列名,
作用:判断外部上下文中是否为该列中的唯一值,做切片器交互时十分有用。
例:
新建度量值[方法 1]
= IF(HASONEVALUE('产品明细'[产品名称]), BLANK(), [大于 2000 万的城市销售金额])
这个度量值的意思是,如果外部上下文在[产品名称]中,用空值表示,否则运算度量值,
结果显示如下,
如果想要总计值为空,和上面的度量值类似,BLANK 换个位置就行了,
新建度量值[方法2],
= IF(HASONEVALUE('产品明细'[产品名称]), [大于 2000 万的城市销售金额], BLANK())
结果如下,和我们期望的一致
SUMX
SUMX(<table>, <expression>)
第一个参数为被运算的表 table
第二个参数是对表中的每一行计算的表达式
这是一个迭代函数,可以对表进行逐行运算,
用该函数建一个度量值[方法3]
= SUMX('产品明细', [大于 2000 万的城市销售金额])
结果如下,总计正好等于明细项之和
SUMX 函数十分强大,有的时候甚至可以代替 CALCULATE,比如用 SUMX 可以一步实现方法 3 的效果,而无需借助 CALCULATE 建立的度量值 [大于 2000 万的城市销售金额]。
使用 SUMX 新建度量值[SUMX 方法],
= SUMX('产品明细', SUMX(FILTER('门店城市', [销售总额]>20000000),[销售总额]) )
结果如下
通过 SUMX 嵌套实现的效果和之前的方法完全一致,其中内层嵌套的 SUMX 公式和之前用
CALCULATE 建的度量值是等效的。不过 SUMX 的计算原理是逐行运算,如果数据量特别
大,这种方式对内存的消耗比较严重,使用这种方式候需要慎重。
EARLIER 函数
前面利用 PowerBI 做数据分析的时候都是对整列的字段进行操作,并没有做更细化的分析,比如分析数据的每一行、提取某一行的数据,这在 Excel 中很容易实现,因为 Excel 公式是对单元格操作。那么在 PowerBI 中能不能按行分析呢,答案当然是肯定的,并且比Excel 更加灵活,借助这个函数:EARLIER.
EARLIER 语法
EARLIER(<column>, <number>)
▪ 第一个参数是列名
▪ 第二个参数一般可省略
▪ EARLIER 函数提取本行对应的该列的值
,实际上就是提取本行和参数列交叉的单元格
这个函数是指定行上下文重要工具,下面靠几个实例来理解这个函数。
EARLIER 应用实例
有一张订单表:
- 01 | 求两个订单的时间间隔
相当于用下一个订单的日期减去当前订单的日期,为了相减的方便,
新建列[下个订单日期],先把下一行的订单日期提取过来,输入 DAX 公式:
新建列[下个订单日期]
= SUMX(FILTER('订单表','订单表'[序号]= EARLIER('订单表'[序号])+1), '订单表'[订单日期])
这个公式的意思是,利用 EARLIER 获取当前行的序号,然后找到当前序号+1 的那一行的订单日期,结果如下,
然后新建一列,用两列日期相减得到间隔的天数,
间隔 = IF([下个订单日期]=BLANK(), BLANK(), [下个订单日期]-[订单日期])
这里用 IF 判断主要因为最后一列为空值,避免出现不合理的数值
- 02 | 求每个订单日期的累计销售金额
新建列[累计销售额],
=SUMX (FILTER('订单表','订单表'[序号]<=EARLIER('订单表'[序号])), '订单表'[销售金额])
利用 EARLIER 求当前行的序号,然后把小于等于当前序号的所有行的销售额累加。 - 03 | 求截至目前订单,每种产品的销量
新建列[产品累计销量]
=SUMX(FILTER( '订单表','订单表'[序号]<=EARLIER('订单表'[序号]) &&'订单表'[产品名称]=EARLIER('订单表'[产品名称])), '订单表'[销售数量])
不仅利用 EARLIER 筛选小于当前行的序号,还利用它求得当前行的产品名称,然后同时符合这两个条件的销量才累加,结果正是我们期望的,
以上几个实例都是先获得本行的记录,然后做各种聚合预算,本行的记录可以称为行上下文,EARLIER 函数正是获取行上下文的最好工具之一[^1]
可视化的制作
柱形图
柱形图就是利用水平的柱子表示不同分类数据的大小
(条形图就是竖的柱形图,柱形图的各项设置也适用于条形图)
有一份整理好的 2006-2015 年各省市三个产业的产值表,
1.堆积柱形图
在画布上放入堆积柱形图,[年度]字段拖入轴中,[第一产业]拖入到值上,一个柱形图就出来了,
因为只有一个序列数值,所以堆积柱形图就是普通的柱形图,加入更多序列才显示出堆积的效果,比如把字段[第二产业]、[第三产业]也拖入到值中,
在这个框里拖动各个字段上下的位置,可以改变图表中各字段数值显示的顺序。
三个序列加入以后就变成了堆积柱形图,显示如下,
特征
⚫ 不同的序列在一根柱子上显示
⚫ 可以直接比较总量的大小
⚫ 分类序列的数值比较功能弱化
2.簇状柱形图
选中刚才制作的堆积柱形图,在可视化区域点击簇状柱形图,刚才的图表就变成了簇状柱形图,
特征:
⚫ 不同序列使用不同的柱子
⚫ 可以比较各序列的数值大小
⚫ 总量比较功能弱化
3.百分比堆积柱形图
再次选中该图表,然后点击百分比堆积柱形图,图表就变成这样了,
特征:
⚫ 与堆积柱形图类似,不同序列在一根柱子上显示
⚫ 显示各序列的相对大小,Y 轴标签变为百分比
⚫ 无法比较总量,每根柱子都一样高
柱形图格式设置
就以上面的堆积柱形图为例,选中该图表,点击格式,
就可以显示每一项图表要素的设置,有开关按钮的要素可以点击打开,然后点击向下的箭头,就可以显示每项要素的细节设置,比如对刚才的簇状柱形图进行如下设置:
⚫ 修改标题文字、并增大字号
⚫ Y 轴网格线变为白色,宽度设为 2 磅
⚫ 三个序列数据颜色更换
⚫ 背景颜色更换
变成了下面的风格
一个合格的柱形图也大抵如此:纵横轴清晰、有图例、有数据单位、和图表呼应的标题,当然还有最养眼的色彩搭
配
树状图
它把整体的数据想象成一颗树,而其中每一个数据就是一个枝叶,不过这个枝叶是放在一个矩形中,然后每一个数据矩形,错落有致的排放在一个整体的大矩形中。
单层树状图
PowerBI 中树状图的生成过程
无论如何拖拽,整体上都保持一个矩形的形状,可以根据画布的空间大小和矩形排列美感选
择一个合适的大矩形,
矩形树图通过每个矩形的大小、位置和颜色来区分各个数据之间的权重关系,以及占总体的比例,使你一目了然的看到整个数据集。
利用树状图来看看各省市的 GDP 排名,
树状图默认各个矩形从上到下、从左向右按面积降序排列的,因此可以很直观的看到每个省市的 GDP 在全国排在什么位置。
树状图不仅可以表示上面单层数据关系,还可以用来展现双层结构。
双层树状图
比如模拟一份各品牌手机的销量数据,
依然在树状图中进行可视化
在单层树状图的基础上添加一个明细字段到【详细信息】中,就成了双层树状图,
每一种颜色的矩形代表一个手机品牌,从这个矩形的大小可以判断各个品牌的整体销量;而在各个品牌矩形内部,又根据各种型号的销量分成一系列小矩形,很直观的表现了两个层级的数据结构。
树状图的使用场景
⚫ 要显示大量的分层数据
⚫ 条形图不能有效地处理大量值
⚫ 要显示每个部分与整体之间的比例
⚫ 要显示层次结构中指标在各个类别层次的分布的模式
⚫ 要使用大小和颜色编码显示属性
⚫ 要发现模式、离群值、最重要因素和异常
平时看到其他图表如条形图、折线图等,在图表内部总有空白区域没有被完全利用上,而在树状图中,没有任何空白区域,每一处都用在了表现数据的关系上,从这方面看,树状图绝对算是空间利用率最高的图表了。
地图可视化
利用内置微软自己的必应地图,在 PowerBI 中可以轻松生成地图来实现各种数据可视化。
在 PowerBI 的默认可视化对象中,有三种地图对象:气泡地图、着色地图和 ArcGIS Map。
1. | 气泡地图-Bubble Map
在地图上利用气泡的大小来表示不同地区的数据,比如展现世界各国的 GDP
可以明显看到世界地图上美国的气泡最大,表示 GDP 最高,而中国和日本的次之。气泡的颜色也可以自定义。
制作步骤如下,
如果有多个层次的位置列,比如上图中是国家层级的位置,再加上省自治区、市级的位置数据,就可以在地图上向下钻取。
以中国数据为例,在中国的层级下添加各个省份的 GDP 数据列,并且在河南省下添加各个地市的 GDP 数据列,然后把这两个字段列拖到位置框中,单击图表右上角的向下箭头,启用“深化”,就可以在地图中向下钻取到下一层级的数据了,如下:
必应地图对于地名的识别有时会有偏差,尤其是对于非英语名称的地理位置,中国地名是否为全称也会有影响,建议都写全称,比如“北京”应该写为“北京市”。
在刚才的中国地图中,台湾和澳门的数据都没有显示出来,如果要保证位置的精确性,把位置的具体经纬度添加进来是必要的。
把省会的经度和纬度分别拖入到【经度】和【纬度】框中,
这样台湾和澳门的气泡图数据都展现出来了。
2. | 着色地图-Filled Map
着色地图和上面的气泡图制作过程基本一样,只是展现数据的方式不是使用气泡,而是用颜色填充的方式**,颜色越深表示数值越大**
着色地图对位置信息的要求比上面的气泡地图要更严格,提供经纬度数据会更容易正常显示,另外还需要把相应字段先设置地理信息分类,并选择和地理位置对应的层级
设置好以后,该字段前面会显示地球状的地理标识。
以后无论使用何种地图可视化,推荐先按上述方式设置好地理信息的字段。
着色地图在 PowerBIDesktop 中总是无法正常显示,可以把数据导入到 PowerBI 在线服务,然后使用着色地图可视化工具可以正常展现出来。
3. | ArcGIS Map
PowerBI 内置的 ArcGISMap,它不是由必应地图提供,而是由 ESRI 提供的,所以第一次使用时会弹出 ESRI 使用条款对话框,点击同意即可。
依然使用上面的数据,使用 ArcGIS Map 可视化,看起来和气泡地图没有什么区别,点击右上角的三个点点,选择编辑,各种强大的功能就在最顶端展示出来了
底图
就是地图的背景画布样式,提供了以下 4 种画布
地图主题
提供了四个地图主题。位置主题就是只显示位置,气泡大小一样;而大小主题就是根据数值的不同显示大小不等的气泡,看看之前没有见过的热图主题,
符号样式
使用符号样式可以对地图上数据的显示方式进行精细调整。比如不想用圆形的气泡,改称方形的
大头针
在搜索框中键入关键字(如地址、地点和兴趣点),再从下拉列表中进行选择。 地图上会显示一个符号,点击会快速定位并会自动缩放到相应位置。
行驶时间
可以选择一个位置,然后确定在指定半径区域或驾驶时间内可用的其他地图功能。
参考图层
可以在地图上添加各种统计信息层,比如在中国地图上添加地势三级阶梯
在图层上还可以交互,点击展示出相关信息
总之,ArcGIS 地图超越地图点表示法的地图绘制技术提升到新的水平。 从基本地图、位置类型、主题、符号样式和引用层中进行选择,创建丰富多彩的信息性地图可视化效果。
PowerBI 常用操作
查看图表背后数据的三种方式
(一)在图表上单击右键,选择“查看数据”
数据可以显示在图表右侧,也可以放在图表下边,数据显示出来后,点击右上角的三个点,还可以导出数据。
若要隐藏数据,返回之前状态,点击“返回报表”即可。
(二)选中图表,然后点击右上角三个点,选择“显示数据”
这种方式,还可以直接导出数据,在“查看数据”上边的功能就是“导出数据”。
(三)选中图表,点击上方【数据/钻取】选项卡“查看数据”
以上三种查看数据的方式,都可以导出数据,平时我们是用自己的数据做的图表,可能觉得导出数据没有什么意义,但有时别人直接发过来一个 pbix 的文件,如果想从这个文件中获取基础数据,导出数据的功能就派上用场了。
利用这种方式导出数据有行数的限制,最多 3 万行,如果基础数据超出 3 万行,这种方式就不行了,当然也有其他解决的办法
图表的钻取
只要是数据结构有层级关系,无论是什么类型,都可以进行钻取操作。
查看可视化图表的时候,我们可能想深入了解某个视觉对象的更详细信息,或者进行更细粒度的分析,比如看到2017年的总体数据,同时想知道每个季度甚至每个月的数据,通过PowerBI的钻取功能,可以点击鼠标轻松实现。
当图表中的数据存在层级结构时,可以在图表上直接下钻展示下一层级的数据,最常见的层级结构就是日期数据,从年度、季度、月份到日期,甚至到小时、分钟和秒,只要具体的日期数据的层次结构足够详细。
为了能够直观看到层次的变化,先用一个矩阵表来展现,把日期表中的日期拖入到【行】框中,Power BI 会自动添加时间层次结构,
如果不想要某个层次,点击右边的叉删除即可。把销售额也拖入到值中,显示的是年度数据,
钻取到下级层级的数据有两种方式:
(一)通过图表右上角的向下箭头“启用深化”。
启用“深化”以后,直接点击需要钻取的数据对象就可以了,操作过程和效果如下:
点击左上角的向上箭头,可以向上一级汇总。
另外左上角还有两个按钮,点击第二个按钮,显示下一层级的数据,
点击左上角第三个按钮,可以同时显示所有层级的数据,
按照以上的操作方式,在柱形图中也可以进行钻取,
(二)使用顶部 Power BI“数据/钻取”选项卡。
点击选中图表,上方按钮区出现“数据/钻取”功能,
通过点击这几个按钮,同样可以实现第一种方法的钻取效果
上面是日期层次的数据钻取,另外一种常见的分层级数据类型就是地理数据,从国家、省份到城市,可以一直往下细分,之前介绍地图可视化对象的时候,也展现过钻取功能,
还有前面介绍的树状图,也经常用来钻取数据,
最后需要注意的是,如果向可视化效果添加日期字段没有自动创建层次结构,则可能是因为“日期”字段实际上并未保存为日期类型。 回到“数据”视图下打开该表,选择包含日期的列,然后在“建模”选项卡中将“数据类型”更改为“日期”或“日期/时间”就可以了。
编辑交互
PowerBI可视化与传统图表的一大区别,就是可视化分析是动态的,通过页面上筛选、钻取、突出显示等交互功能,可以快速进行访问、发现、探索数据背后的规律。但是,不必要的交互会将优异的分析变成无用分析,本文介绍如何恰到好处地使用交互式视图。
下面以这个报表为例,看看PowerBI可视化报表的交互效果
默认情况下,筛选条件应用于该报表上的所有视图,
不仅切片器可以筛选,每一个可视化对象,同时也可以是其他图表的筛选条件;点击任何一个筛选条件,其他图表动态响应,从不同的角度展现数据,但如果筛选使用不当,展现出来的可视化也会令人困惑,比如下面这个,
下方的柱形图展示的所有省份的GDP排名,可是一旦利用左方的省份切片器进行筛选,柱形图只展示了被选中的省市数据,其他数据被筛选掉了,显然与我们的初衷不符,那如何进行设置呢?
选中任何一个可视化对象,在 Desktop 中,点击“格式”>“交互”,选择“编辑交互”,
以看到每一个可视化对象上方都出现了两个图标:
针对现在选中的筛选条件,对每个可视化对象进行设置:
- 如果需要响应该筛选,则选择“筛选”图标
- 如果不希望被筛选,则选择“不起作用”图标
切片器
Power BI是存在切片器的, 其主要用于筛选数据达到我们需要的数据,也就是说,改变上下文,使得计算结果在我们需要的上下文进行。
创建:
切片器的创建很简单,只需要在视觉对象中选择切片器,然后在字段中放入自己需要的字段即可,如下:
作用:
之前就说过,切片器是对原有数据的筛选(上下文的改变)。比如下面的演示,当我们用大部做切片器时,选择不同的大部,等同于筛选不同大部的数据,所有展现的结果也跟着变化。
切片器可以叠加,也就是多个切片器同时控制同一个报表
原文(未整理)
问题
01 | DAX 书写错误
刚开始在 DAX 编辑框建度量值时,总是眼前一堆红色的波浪线有没有,
实出现这个问题一般都是少了右括号,忘记输入逗号或者有中文字符等
编写 DAX 时一定要切记:
▪ 每一个函数左右括号()
要配对;
▪ 引用表的单引号 ''
不要漏;
▪ 参数之间的分隔逗号 ,
不能缺少;
▪ 以上字符均要求为英文字符
;
一定要按照格式规范书写 DAX:原文
02 | 函数使用错误
有些函数返回的表,若用于新建度量值,肯定返回错误,比如,
度量值需要返回的是一个值,而 FILTER 函数返回的表,所以它不能单独用于建度量值,但该函数可以作为其他函数的参数使用,来建立度量值。
虽然上图中的 FILTER 函数建度量值时出错,但是却可以建表,该表达式将返回所有北京的客户的订单表。
也有些函数返回的是值,若用于建表,也会报错,比如
CALCULATE 函数返回的是一个值,不能用于建表。不过如果你确实想建一个只有一个值的表,也是可以做到的,可以在这个表达式外层套一个大括号{}
,正常返回一个表,
该表只有一个数据,为北京客户贡献的销售额。
通过这种方式,也可以用于在数据视图下,查看度量值的返回结果
03 | 参数使用错误
参数错误的时候,有时并不会有红色波浪线提醒,比如下图,
提示 MAX 函数的参数只接受列,该错误就是参数应该为列的时候,使用了表。
还有的函数应该引用表,却用了列或者值,
出现这种情况就是按照错误提示进行更改,再仔细研究一下该函数的介绍文档,弄清楚该函数需要有几个参数,以及每个参数分别是什么类型。
关于函数和参数的错误,主要是要理解 DAX 各类函数及其参数的用法,
DAX中的表函数和值函数
04 | 显示结果不符合预期
写度量值时没有任何错误提示,把它拖入到图表中也没有错误,可是显示的数据却很奇怪,完全不是想象中的,
所有的数据都相同,没有按上下文进行计算?
这个问题一般都是维度表和事实表没有建立关系,或者没有建立正确的关系,因此度量值没有按照外部下上文正确计算。
遇到这种情况去建模视图下,更改一下关系就可以了。
这里也建议伙伴们,导入数据之后,先在建模视图下建立正确的关系图,然后再去着手去
写度量值。如果系统自动建立的,也要检查一下,自动建立的关系是否与我们的分析逻辑
一致
05 | 使用度量值作为筛选维度
还有不少人问我,为什么我建立的度量值无法拖入到图表里,我仔细一看,原来 TA 是想用这个度量值拖到图表的轴上,或者是切片器中。
度量值作为动态的公式,只有在一定的上下文环境中才有确定的返回结果,所以 PowerBI中默认它是不能作为筛选维度的。如果确实需要用这个维度,就去构建一个表吧。
06 | 排序错误
当把文本字段放到坐标轴或者切片器上,显示的顺序都乱了,完全不是自己想要的,就像下面这些,
以上这些都是文本类的数据,文本数据默认是按照字母来排序的,但是这样的排序明显与我们的初衷不符,在图表的排序或者切片器的设置中,又没有办法直接调整过来,那怎么办呢?
解决办法:PowerBI 中有个功能,可以轻松排序,它就是:按列排序。
以调整中文的月份字段为例,来看看这个功能是怎么使用的。
日期表中已经有数字的月份,那么可以选中中文字段[月度],点击“按列排序”,下拉框中选择“月份”,
然后中文的月度,就按照数字顺序来进行排列了
其他文本的排序都可以用这种方式来进行设置,不过首先一定要有对应的数字序列。
当我们添加有顺序要求的文本数据时,一定要同时给这些文本添加序号,比如上一
篇文章(PowerBI 技巧: 动态 切换 数据 单位 )中的金额单位,在输入数据的时候,同
时添加了序号,
如果不这样做,在切片器中不会按照从小到大的单位顺序来排列(当然这个例子中用单位值也可以排序)。
所以养成为文本数据添加数字索引的好习惯,在任何场景下的文本排序都不再是问题。
操作
1.复制列
点击列名选中要复制的列,右击鼠标,点击重置列就可以了(英文版就是点击Duplicate Column),这样表中就会多一列新的和你要复制的列100%一致的列。
补充
1.二维表:
- 二维表就是由行列组成的,知道行号列号就可以确定一个表中的数据,这是二维表的特点。在关系数据库中,存放在数据库中的数据的逻辑结构以二维表为主.
- 在二维表中惟一标识元组的最小属性值称为该表的键或码。二维表中可能有若干个健,它们称为表的侯选码或侯选健。从二维表的所有侯选键选取一个作为用户使用的键称为主键或主码。表A中的某属性集是某表B的键,则称该属性值为A的外键或外码。
二维表和一维表的区别:
-
一维表,一行或者一列就是完整的信息
-
二维表单独的行列读不出完整的信息。
-
一维表:将表头(列名称)删除,没影响
二维表:将表头(列名称)删除,数据无法解释 -
一维表是指表格的每个字段都是事物的属性,而不是具体形态,如字段 是月份而不是一月、二月、三月…,是性别而不是男、女,是所在部门而不是财务部、行政部;每一条记录都是在一次性产生的。
-
二维表的字段通常包含属性的具体形态,如一月、二月、三月…;男生人数、女生人数;部门人数等。
这个表格是二维表,为了分析的方便,需要把二维表转化为一维表,这个操作在 Power BI里非常简单,这里把三个产业结构的数据转化为一个字段,选中地区和年度列,从转换里找到逆透视其他列: -
例1、二维表,大部分字段都是属性的具体形态。
-
-
例2、一维表,每个字段都是属性,而不是具体的形态。
-
通俗来讲,一维表就是明细记录表,二维表就是统计汇总表。
-
一维表(明细记录表)是用来详细记录信息的,是数据库;二维表(统计汇总表)是用来展示各类情形下的统计分析结果的,是进行决策的基础。
-
一维表通常用于采集原始数据、基础数据、记录流水等理为详尽的信息。
-
二维表通常作为最终报表,提供给报表使用者,方便报表阅读者快速掌握重要信息,汇总或分类信息,分析或决策信息。
2.上下文
- 在DAX中,通过上下文概念来定义
函数所在的环境变量
,即其运算范围
,实现了函数对数据的处理可以根据上下文的不同而输出不同的运算结果。 - 上下文,是英文context翻译过来的,上下文表示环境、范围。在PowerBi的DAX函数库涉及到两类上下文:行上下文(Row Context)和筛选上下文(Filter Context)。
要理解以下两个概念:
- 数据表的结构。在数据库中,表是由行列组成,定义表时需指定列名、类型,而数据是一行行存储的。
- 行的迭代。实际就是循环读取行数据的意思,比如for row in rows循环。
1)行上下文(Row Context)
行上下文可以理解为当前行内容。行上下文的应用范围不只局限于当前一张表。如果两张表之间建立了关联关系,则通过该关联关系就形成一个跨表的行上下文。[^1]
2)筛选上下文(Filter Context)
筛选上下文是指将原始数据按照一定规则进行筛选
,然后将提取出来的结果再作为环境变量带入到函数中使用。通过设定筛选上下文,可以灵活的改变函数的运算范围,实现数据分类分析处理的目的。
PowerBI中函数的上下文:
- 行上下文函数:指的是该
函数对数据的读取是逐行进行的
,依据每行的数据进行计算。因此就有行上下文只管迭代的说法,就是循环读取每行数据
。 - 筛选上下文函数:指的是该函数受数据列筛选的影响。列筛选可以理解为Excel中筛选列的操作。
那么哪些是行上下文函数?哪些是筛选上下文函数呢?比较典型的:
- 行上下文:
- 新建列。在PowerBI中,新建一个数据列实际是对现有表中的数据进行计算,比如:列3=列1-列2,可以理解为对表中数据逐行读取,用每行的第1列数减去第2列得到的数组成第3列。但是如果在新建列中用了聚合函数,比如sum,那么就会忽略行上下文,从而得到一个唯一值。
- 以X结尾的函数,这类函数是
专门用于逐行计算的函数
,比如:sumx,得到的是逐行计算的数组。
- 筛选上下文:
- 度量值。度量值是对列进行计算,因此受列筛选的影响。比如:列1中有A、B、C三个数据,countrows(列1)(countrows为计算行数的函数)在没有筛选的情况下,countrows(列1)=3。如果对列1进行筛选了A,那么列1只剩下A这1个数据,所以countrows(列1)=1。形象的理解可以类比Excel中筛选操作,列1筛选了A,那么B、C都被隐藏,所以只剩下A一个数据。在PowerBI矩阵表和Excel透视表中,行标签代表着对列的筛选,因此可以实现分类统计。
在对上下文的理解中,需要注意的是:使用聚合函数(统计函数)会自动忽略行上下文,因为聚合函数本来就是就列进行统计
- 度量值。度量值是对列进行计算,因此受列筛选的影响。比如:列1中有A、B、C三个数据,countrows(列1)(countrows为计算行数的函数)在没有筛选的情况下,countrows(列1)=3。如果对列1进行筛选了A,那么列1只剩下A这1个数据,所以countrows(列1)=1。形象的理解可以类比Excel中筛选操作,列1筛选了A,那么B、C都被隐藏,所以只剩下A一个数据。在PowerBI矩阵表和Excel透视表中,行标签代表着对列的筛选,因此可以实现分类统计。
需要记住的是,DAX的行上下文和筛选上下文共同作用于函数运算当中并对其结果产生影响。在分析行上下文对函数结果的影响时要以当前行中的数据为研究基准,而分析筛选上下文对函数结果的影响时则要从筛选出的子表单入手进行。
当创建计算列时,DAX会自动为其定义行上下文关系,即计算列中的每个值都受到其所在行数据的影响。而当使用度量值创建报表时,其运算都是基于表单中其他条件生成的筛选上下文而进行的。
————————————————
原文链接:https://blog.csdn.net/LuYi_WeiLin/article/details/99216271
常用函数FILTER、ALL、CALCULATE三者与上下文关系
用一个例子,公路自行车占各省的销售金额以及占各省销售的占比
FILTER:带入一个新的行上下文,不会影响原有的上下文,可以被切片
ALL:完全用自身所有数据,其他行/筛选上下文不起作用
CALCULATE:针对公式里面列会强行替换原有上下文,其他不受影响
1)内部上下文
- 内部上下文就是创建度量值的 DAX 公式,它的查询筛选函数可以扩大、限制或者重置外部上下文
2)外部上下文- 外部上下文就是外部可以看得见的筛选:标签和切片器
————————————————
此文章为本人学习笔记,学习资料来自微信公众号 PowerBI星球
原文链接:https://blog.csdn.net/waterxmanpro1/article/details/127086439
原文链接:https://blog.csdn.net/LuYi_WeiLin/article/details/99216271