Table.Pivot

官方说明:

给定一对表示属性-值对的列,将属性列中的数据旋转为列标题。
Table.Pivot( table as table, pivotValues as list, attributeColumn as text, valueColumn as text, optional aggregationFunction as nullable function) as table

解读:

相信很多同学是被Power Query的透视列与逆透视功能惊艳到从而喜欢上Power Query的,今天就来扒一扒她的衣服。
源表如下,姓名与科目组合项无重复。

语法咱就不说了,反正英语你也头痛,动下鼠标就开讲吧!
从源表转换成上图的二维表对于M语句写来就显得很潇洒:= Table.Pivot(源,List.Distinct(源[科目]),"科目","分数")
 

第二参数:

第一参数就是要透视的表,这个不多说,我想在这里和大家探讨的就是后面几个参数。先拆解下参数吧,看第二参数产生一个需要放到列区域的不重复字段序列,= Table.Pivot(源,{"语文","数学","英语","扯淡"},"科目","分数")
显然改成这样是没毛病的,有啥意义呢?写成下面又怎样呢?
= Table.Pivot(源,{"扯淡","数学","英语","语文"},"科目","分数")

 
这样呢?= Table.Pivot(源,{"扯淡","数学","英语"},"科目","分数")

起到了字段顺序限定和字段选择输出的效果。
 
有的同学想起了Table.Group,又要任性一把,= Table.Pivot(源,{},"科目","分数")

擦!居然又去重复了…
 
你真的以为是简单的去重复的时候,他又调皮了:= Table.Pivot(源,{},"姓名","姓名")= Table.Pivot(表,{},"科目","科目")

没错他把后面参数中的列给干掉了,顺便自己组队排序、多列都要自己排序,看来他也是个强迫症患者啊!
 
字段能减必然可以増,= Table.Pivot(源,{"骚气","语文"},"科目","分数"),虽然现在的我不知道这个骚气的应用有什么卵用…

其实我枚举第二参数的目的还有一个就是:在大家测试函数参数时可以根据默认产生的语句进行大胆的想象、搞大了可以不负责哦!
 

第三、四参数:

对于第三参数和第四参数,虽然平时一般不会用到以下看似怪异的用法、但还是有必要说一下他的透视数据分布情况!

当只有两列,观察参数中引用的参考字段,如果此时科目二字换为姓名会怎样?

你不会有疑问吗?为啥值区域又是姓名?那么他究竟是怎么分布数据的呢?
我的理解:该情况下,第二参数作为列字段没有疑问,那么这个第三参数到底起什么作用?我的猜想是仅仅作为与第二参数的比较的一个依据。
如果在第二参数内就提取,没有就舍弃,再说第四参数值区域摆什么?首先我们的搞清楚一个前提,除开第三、第四参数此时还有哪些列没引用到,他们去哪儿?
没错,那些没有引用的列会按原有顺序先后放在我们所说的透视表的行区域,如果你此时源表是三列、必然有两列放在了行区域(他就是传说中的后妈生的)!
话说回来,值区域填什么?如果此时第四参数引用的依据列与前面引用列参数重复、则拿此时行区域的第一列放值区域、你可以用第五参数进行值对象转换!
如果此时第四参数与前面引用列不同,则才真正启用该引用列,把他作为值区域转换依据对象!

再回过头来看极简形式的单列表同样满足上述透视的计算法则(下面源表仅有一个科目列)



当我们的列区域放入的字段列表(第二参数)与第三参数的参照列对象不匹配、或部分匹配时,值区域将会全部或部分出现缺失!


一句话总结:瞄一眼第三第四参数、没引用的列按顺序放行区域;第二参数控制实际显示的列字段区域列名;值区域由第二第三参数匹配与否决定(匹配则当第四参数与第三参数不同时启用第四参数列做值转换对象、相同则用此时行区域的第一列做值区域转换对象;不匹配直接值区域值出现缺失!)
 

第五参数:

第五参数要你干嘛?做聚合?这里一对一貌似做聚合多余啊,的确该情况下多余,你也可以写为:
= Table.Pivot(源,List.Distinct(源[科目]),"科目","分数",List.Sum)

 
不光List.Sum,你就一个值、最大最小也是可以的啊,甚至= Table.Pivot(源,List.Distinct(源[科目]),"科目","分数",each _{0})

 
看到这里就有点意思了,貌似最后的值有可能不是一个单值的情况,那么就可以用其他函数对这不止一个的值对象进行转换操作。
 
= Table.Pivot(源,List.Distinct(源[姓名]),"姓名","科目",each Text.Combine(_,"/"))

再举一个例子:
= Table.Pivot(源, List.Distinct(源[科目]), "科目", "分数", each Text.Combine(List.Transform(_,Text.From),"/"))

4 Replies to “Table.Pivot”

  1. 个人理解第5参数是聚合和计算用的,Excel里Pivot的值区域单元格相当于是子集,也就是一个list,在PQ里这个意思也是一样的。前面只要理解了行、列、值区域放的是,第5参数就理解了,但是功能比数据透视表更强大,比如,最后一个案例,我试了一下以下的写法:= Table.Pivot(更改的类型,List.Distinct(更改的类型[科目]),"科目","分数",each List.Sum(_)*10),把结果求和聚合后再进行*10的运算。个人观点,供参考。

  2. 二参看做是匹配键,三参看做要匹配字段的键,四参看做匹配后要返回的值;其中二三参同vlookup的前两参意思差不多,基准值、匹配域,如果不匹配,那就没有透视后的字段名,随之对应的四参值域也消失,即三、四参字段列被删除,源表剩余列升序排列后左侧显示;如果完全匹配,则返回四参的值域,如果部分匹配,则不匹配项以新列null呈现;现在最新版2021版本下,二、三、四参如果同字段,则左侧剩余列、字段列为二参非重值、值域即四参值为对应的三参字段值。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注