
如何在Power BI中根据条件列提取数值?
第三个参数,是需要应用的函数。state代表的是原始值,current代表的是现在从positions里面提取的值。在第一轮循环中,state是原始值即空值"",current是positions的第一个值,这里肉眼可见是0。然后应用Text.Combine()函数来整合字符,因此在第一轮的输出值是"" + "," + list1{0} = ",Model-A"。在第二轮循环中,state是第一轮
假设有一原始数据如下:
想得到一个新列如下:
逻辑是,如果Indicator的值为1,提取Model中对应位置的值。
如果这个问题放在一般编程环境如Python,是比较简单的。只需要构建一个json(或者叫字典),然后提取json的key = 1对应的值即可。
但是如果在Power BI或者Excel环境,它们并 没有自带构建json的功能,只能寻求他法。
DAX明显不是一个选择,因为DAX是用于动态激素按,并不擅长数据变换。
那么剩下就只有Power Query里面的M代码了。
实际上,即使无法使用跟Python一样的方法, 但可以跟随其思路。第一步,先把两列的数据类型从字符转换为列表:
let
list1 = Text.Split([Model],","),
list2 = Text.Split([Indicator],","),
然后提取list2中,数值为1的位置号码:
positions = List.PositionOf(list2, "1", Occurrence.All)
值得一提的是,这里Occurence.All是必须项。因为这个函数默认只提取第一个符合的数值,我们这里需要提取所有符合的数值,所以特意加上这个参数。
下一步,如果是在Python,就是把positions做一个循环,提取list1[i]即可。
可惜,M代码自己并没有类似for循环的功能,这里的关键是用到List.Accumulate()函数来代替:
List.Accumulate(positions,
"",
(state, current)=> Text.Combine({state,list1{current}}, ","))
代码解释:第一个参数是需要做循环的列表,这里是positions;第二个参数,是输出的起始值,这里使用""来构建空值即可;第三个参数,是需要应用的函数。state代表的是原始值,current代表的是现在从positions里面提取的值。在第一轮循环中,state是原始值即空值"",current是positions的第一个值,这里肉眼可见是0 。然后应用Text.Combine()函数来整合字符,因此在第一轮的输出值是"" + "," + list1{0} = ",Model-A"。在第二轮循环中,state是第一轮的输出值",Model-A",current是positions的第二个值,肉眼可见是3 。应用函数后输出值为",Model-A" + "," + list1{3} = ",Model-A,Model-D"。
详细的M代码为:
let
list1 = Text.Split([Model],","),
list2 = Text.Split([Indicator],","),
positions = List.PositionOf(list2, "1", Occurrence.All)
in
List.Accumulate(positions,
"",
(state, current)=> Text.Combine({state,list1{current}}, ","))
现在的输出效果为:
看着不错,但不够完美。这里可以简单应用Text.Range()函数来去掉第一个逗号:
let
list1 = Text.Split([Model],","),
list2 = Text.Split([Indicator],","),
positions = List.PositionOf(list2, "1", Occurrence.All)
in
Text.Range(List.Accumulate(positions,
"",
(state, current)=> Text.Combine({state,list1{current}}, ",")),1)
得到我们想要的新列:
谢谢阅看。
更多推荐
所有评论(0)