
在实际的数据清洗与转换过程中,替换是必不可少的动作,并且很多时候需面临各类复杂的替换,因此与替换相关的操作值得花时间去深究。
Table.ReplaceValue()
Table.ReplaceValue()函数用于将表中新、旧值进行替换,第2个和第3个参数为any(任意类型,如列表、文本或数值等),第4个参数为参数函数(replacer替换器函数),这3个参数是Table.ReplaceValue()函数的核心。Table.ReplaceValue()函数的拓展性强,可应用于各类复杂的替换场合,语法如下:
Table.ReplaceValue(table as table,oldValue as any, //YnewValue as any, //Zreplacer as function, //分ReplaceText或ReplaceValue两种情形columnsToSearch as list //X) as table
1
●
基础语法
该函数常用于各种场合的横向填充、纵向替换。理解与上手该函数的最有效的方式是通过Power Query编辑器中的图形化操作为“转换”→“替换值”获取该函数的完整代码,然后进行代码的修改。通过“数据”→“从表格”将数据导入Power Query编辑器,数据源如图9-55所示。

■ 图9-55 数据源
以表内的“横向填充”为例。操作步骤如下: 单击“城市”列,选择“转换”→“替换值”→“替换值”。对于一些复杂的替换场景,出于后续修改的需要,可先预设置一些个人习惯的占位符。例如,将“要查找的值”设置为null,将“替换为”设置为0,单击“确定”按钮,如图9-56所示。

■ 图9-56 替换值
在编辑栏查看显示的代码如下:
= Table.ReplaceValue(源,null,"0",Replacer.ReplaceValue,{"城市"})
在以上代码中,0值是临时占位的一种应用。
如果要替换的列为两列或者更多列也是允许的。例如,选择“省份”和“城市”两列,选择“转换”→“替换值”→“替换值”,将null替换为0。在编辑栏查看显示的代码如下:
= Table.ReplaceValue(源,null,"0",Replacer.ReplaceValue,{"省份", "城市"})
对比显示的这两个代码块不难发现。Table.ReplaceValue()函数的第5个参数可以轻松地进行列选择,在图形化操作界面中操作时很好理解,但如果代码化来完成{"城市"}或{"省份", "城市"},对于初学者来讲则相对不易理解与记忆。
修改上面的第1个代码块,对表内的数据实施引用(注意: 第2个和第3个参数在引用或调用的过程中,前面必须加each),实现横向填充,代码如下:
= Table.ReplaceValue(源,null,each [省份],Replacer.ReplaceValue,{"城市"})
实现的效果如图9-57所示。

■ 图9-57 横向填充
在“高级编辑器”中查看的完整代码如下:
//ch9-053let源 = Excel.CurrentWorkbook(){[Name="表6"]}[Content],替换 = Table.ReplaceValue(源,null,each [省份],Replacer.ReplaceValue,{"城市"})in替换
以上操作也能通过表间数据的调用与匹配实现。导入“表6”和“表6A”,用“表6A”中的数据替换“表6”中的空值,数据源如图9-58所示。

■ 图9-58 数据源
在“高级编辑器”中查看的完整代码如下:
//ch9-054letA = Excel.CurrentWorkbook(){[Name="表6A"]}[Content],源 = Excel.CurrentWorkbook(){[Name="表6"]}[Content],替换 = Table.ReplaceValue(源,null,each A{[省份=[省份]]}[城市],Replacer.ReplaceValue,{"城市"})in替换
返回的值与图9-57所示的值相同。
或者,将第4个参数更改为自定义函数,在编辑栏显示的代码如下:
= Table.ReplaceValue(源,null,each [省份],(x,y,z)=>if x is null then z else x,{"城市"})
返回的值与图9-57所示的值相同。在“高级编辑器”中查看的完整代码如下:
//ch9-055let源 = Excel.CurrentWorkbook(){[Name="表6"]}[Content],替换 = Table.ReplaceValue(源,null,each [省份],(x,y,z)=>if x is null then z else x,{"城市"})in替换
在以上代码中,通过自定义的方式来定义参数函数从而控制替换前、替换后的值。本案例中,y 值(替换前的值)没有参与运算。
2
●
进阶语法
Table.ReplaceValue()函数威力的大小在于第2个、第3个和第4个参数的协同应用的深度。第2个参数(y)为替换前的值,第3个参数(z)为替换后的值,第4个参数为替换器函数(当替换的过程中不需要自定义参数函数时,该函数保持系统生成的原样即可)。
有关第2个参数的补充: 将null值替换为0是最简单、最易理解的单值替换。以“表3”为例,在实际应用场景中,将([Q1]+[Q2])185或者List.Sum({[Q1], [Q2]}) 185的“城市”添加“(A+)”标识。此时的第2个参数已经是多值或列表,这种情形也是允许的,但需要第3个和第4个参数的配合才能产生效果。
有关第3个参数的补充: 将null值替换为0是最简单、最易理解的单值替换。在实际应用场景中,第3个参数可能为{“(A+)”,“(A)”,“A-”},它是也允许的,但需要第2个参数与第4个参数的配合才能完成。
有关第4个参数的补充: 在默认情况下,系统生成的样式为Replacer.ReplaceValue(精确匹配)或Replacer.ReplaceText(模糊匹配)。以Replacer.ReplaceValue为例,它其实是(x,y,z)= Replacer.ReplaceValue(x,y,z)的简写; 其中x 对应的是选择一列或多列,y 为替换前的值,z 为替换后的值。当将此参数函数修改为自定义函数时,必须先理解x、y、z所代表的对象,然后理解替换对象间的逻辑关系,这样才能正确、高效地进行替换。
3
●
进阶应用
在Table.ReplaceValue()函数的5个参数中,第2个、第3个和第4个参数需重点理解。在运用自定义函数的过程中,第5个参数(Columns)为x、第2个参数为y(oldValue)、第3个参数为z(newValue),它是第4个参数中x、y、z 的对应值(注意: 第4个参数在应用过程中可能不需要x、y、z 全部上场,它们三者中的1个或2个上场也是允许的,视实际需要而定)。
以“表6”为例,当第2个参数为列表时,通过第4个参数的协同来完成相关替换,完整代码如下:
//ch9-056let源 = Excel.CurrentWorkbook(){[Name="表6"]}[Content],替换 = Table.ReplaceValue(源,{"北京","上海","广州","深圳"},"一线",(x,y,z)=> if List.Contains(y,x) then z else x,{"省份", "城市"})in替换
以上代码中,第2参数为列表,所以第4参数必须用列表函数来控制。运行结果如图9-59所示。

■ 图9-59 ch9-056的运行结果
以“表3”为例,代码如下:
//ch9-057let源 = Excel.CurrentWorkbook(){[Name="表3"]}[Content],取一部分数据 = Table.AlternateRows(源,1,2,1),替换 = Table.ReplaceValue(取一部分数据,each {[Q1],[Q2]},"(A+)",(x,y,z)=> if List.Sum(y)>185 then x&z else x,{ "城市"})in替换
以上代码也可以更改,更改后的代码如下:
//ch9-058let源 = Excel.CurrentWorkbook(){[Name="表3"]}[Content],取一部分数据 = Table.AlternateRows(源,1,2,1),替换 = Table.ReplaceValue(取一部分数据,each [Q1]+[Q2],"(A+)",(x,y,z)=> if y>185 then x&z else x,{"城市"})in替换
以上两个代码块返回的值完全相同,如图9-60所示。

■ 图9-60 ch9-058的运行结果
当第2个和第3个参数都为列表时,通过第4个参数来控制替换对象是允许的,第5个参数为多列也是允许的,代码如下:
//ch9-059let源 = Excel.CurrentWorkbook(){[Name="表3"]}[Content],取一部分数据 = Table.AlternateRows(源,1,2,1),类型 = Table.TransformColumnTypes(取一部分数据,{{"排名", type text}}),替换 = Table.ReplaceValue(类型,each {[Q1],[Q2]},{"(A+)","(A)","(A-)"},(x,y,z)=> if List.Sum(y)>185 then x&z{0}else if List.Sum(y)>165 then x&z{1} else x&z{2},{"城市","排名"})in替换
运行结果如图9-61所示。

■ 图9-61 ch9-059的运行结果
从以上学习中不难发现: 学习M 语言的价值在于能够实现图形化操作所不能实现的功能。低成本的学习方法在于: 对于难于理解与记忆的函数,可以先通过图形化获取相关代码,然后在系统生成的代码的基础上进行代码的修改。
Table.ReplaceErrorValues()
Table.ReplaceErrorValues()函数用于将错误值替换为指定的新值,语法如下:
Table.ReplaceErrorValues(table as table,errorReplacement as list) as table
应用举例,代码如下:
//ch9-060leta= #table({"运单","客户"},{{"YD001","王2"},{"YD003","张3"}, {"YD005","李"&4}})ina
返回的值“YD005”的“客户”列存在错误,如图9-62所示。

■ 图9-62 存在错误值的表
在 Power Query编辑器中,选择“客户”列,单击“转换”→“替换值”→“替换错误”。在“替换错误”对话框中输入值(例如,“李4”),单击“确定”按钮,如图9-63所示。

■ 图9-63 替换错误
在编辑栏显示的代码如下:
= Table.ReplaceErrorValues(a, {{"客户", "李4"}})
将以上代码中的{{"客户", "李4"}}(两对花括号)替换为{"客户", "李4"}(1对花括号)是允许的。
Table.Transpose()
Table.Transpose()函数用于表的转置,使列变为行、使行变为列。此函数的用法较为简单,语法如下:
Table.Transpose(table as table,optional columns as any) as table
应用举例,代码如下:
//ch9-061let源 = Excel.CurrentWorkbook(){[Name="表1"]}[Content],降级 = Table.DemoteHeaders(源),转置 = Table.Transpose(降级)in转置
运行结果如图9-64所示。

■ 图9-64 ch9-061的运行结果
参考书籍

《深入浅出Power Query M语言》
ISBN:9787302602828
黄福星 编著
定价:100元

内容简介
本书系统阐述Power Query M语言从基础到进阶的应用,包括应用流程、应用技巧等。本书通过一种易于理解的方式,旨在让读者用一个月的时间,系统、全面地掌握M语言。
全书共分为5篇:第一篇为入门篇(第1和2章),第二篇为基础篇(第3~5章),第三篇为强化篇(第6~8章),第四篇为进阶篇(第9~11章), 第五篇为案例篇(第12章)。书中主要内容包括Power BI简介、Power Query基础、M语言基础、文本处理、时间智能、数据转换、数据处理、数据分组、数据获取、综合应用。
本书适用于零基础学习Power Query M语言的读者,包括财务、人事行政、电商客服、质量统计等与数据分析密切相关的从业人员,也可作为高等院校、IT培训机构、其他编程爱好者的参考用书或教材。
编辑推荐
本书以M语言中高频使用的函数为依托,通过一组简单、易于理解的数据源并且方便读者动手实践的方式,循序渐进地讲解,以此来演绎上百个实用案例,从而有效地实现本书的写作目标:“让所有的读者一个月之内对M语言函数有一个直观、清晰的了解,并能轻松上手”。











