Power BI中Fuzzy Grouping是否已停用?求高效替代方案
解决Power BI中批量模糊分组统一客户账户名的问题
先确认Fuzzy Grouping功能状态
Fuzzy Grouping并未停用,它属于Power Query的高级编辑器功能,默认可能未显示在界面,可通过以下步骤开启:
- 打开Power Query编辑器,点击
文件>选项和设置>查询选项 - 进入
预览功能,勾选模糊分组和模糊匹配,重启Power BI后就能在转换选项卡找到该功能
批量模糊分组的实现步骤
若已找到功能但不知如何批量处理,按以下操作:
- 在Power Query中加载20万行数据集
- 选中需要统一的客户账户名列
- 点击
转换选项卡,选择模糊分组 - 在弹出的配置框中:
分组依据选客户账户名列- 新列名设为
标准化账户名 - 调整相似度阈值(默认0.8,账户变体差异大就调低,差异小则调高)
- 勾选
忽略大小写、忽略标点符号、忽略常用词(可把PTY、LTD这类后缀加入常用词列表)
- 点击确定后,Power Query会自动批量将相似账户名分组,生成标准化名称
替代方法(若Fuzzy Grouping仍无法使用)
方法1:自定义Power Query函数批量处理
如果界面功能无法使用,可在高级编辑器中编写M代码实现批量模糊匹配:
// 定义模糊匹配函数 let FuzzyMatch = (inputList as list, threshold as number) as table => let // 列表转表 Source = Table.FromList(inputList, Splitter.SplitByNothing(), {"原始名称"}), // 添加索引 AddIndex = Table.AddIndexColumn(Source, "索引", 0, 1), // 自连接表对比所有名称对 SelfJoin = Table.NestedJoin(AddIndex, {"索引"}, AddIndex, {"索引"}, "匹配项", JoinKind.LeftOuter), // 展开匹配项并过滤自匹配行 ExpandMatches = Table.ExpandTableColumn(SelfJoin, "匹配项", {"原始名称"}, {"匹配名称"}), FilterSelf = Table.SelectRows(ExpandMatches, each [索引] < Table.PositionOf(ExpandMatches, _)), // 计算Jaccard相似度 AddSimilarity = Table.AddColumn(FilterSelf, "相似度", each let str1 = Text.Lower([原始名称]), str2 = Text.Lower([匹配名称]), set1 = List.Distinct(Text.ToList(str1)), set2 = List.Distinct(Text.ToList(str2)), intersection = List.Intersect({set1, set2}), union = List.Union({set1, set2}) in if List.Count(union) = 0 then 1 else List.Count(intersection)/List.Count(union) ), // 筛选符合阈值的匹配 FilterThreshold = Table.SelectRows(AddSimilarity, each [相似度] >= threshold), // 分组并整理匹配组 GroupNames = Table.Group(FilterThreshold, {"原始名称"}, {{"匹配组", each [匹配名称]}}), // 合并原始数据与匹配组 MergeGroups = Table.NestedJoin(Source, {"原始名称"}, GroupNames, {"原始名称"}, "匹配组", JoinKind.LeftOuter), ExpandGroups = Table.ExpandListColumn(Table.ExpandTableColumn(MergeGroups, "匹配组", {"匹配组"}, {"匹配组"}), "匹配组"), // 取出现次数最多的名称作为标准化名称 CountOccurrences = Table.Group(ExpandGroups, {"原始名称", "匹配组"}, {{"出现次数", each Table.RowCount(_)}}), SortByCount = Table.Sort(CountOccurrences, {{"出现次数", Order.Descending}}), KeepTop = Table.Distinct(Table.SelectColumns(SortByCount, {"原始名称", "匹配组"})), RenameColumn = Table.RenameColumns(KeepTop, {{"匹配组", "标准化账户名"}}), // 合并回原始表并填充缺失值 FinalJoin = Table.NestedJoin(Source, {"原始名称"}, RenameColumn, {"原始名称"}, "标准化", JoinKind.LeftOuter), ExpandFinal = Table.ExpandTableColumn(FinalJoin, "标准化", {"标准化账户名"}, {"标准化账户名"}), FillMissing = Table.ReplaceValue(ExpandFinal, null, each [原始名称], Replacer.ReplaceValue, {"标准化账户名"}) in FillMissing in FuzzyMatch
调用方法(替换你的数据源为实际数据源):
let Source = 你的数据源, // 提取客户账户名列转为列表 AccountNames = Source[客户账户名], // 调用函数,阈值设为0.7可按需调整 MatchedTable = FuzzyMatch(AccountNames, 0.7), // 合并回原始表 FinalTable = Table.NestedJoin(Source, {"客户账户名"}, MatchedTable, {"原始名称"}, "标准化信息", JoinKind.LeftOuter), ExpandFinal = Table.ExpandTableColumn(FinalTable, "标准化信息", {"标准化账户名"}, {"标准化账户名"}) in ExpandFinal
方法2:字符串预处理后常规分组
先对账户名做标准化预处理,再用普通分组功能:
- 转小写:
Text.Lower([客户账户名]) - 移除标点:
Text.Remove([客户账户名], {".", ",", "(", ")", " "}) - 移除常用后缀:
Text.Replace([客户账户名], "pty ltd", "")、Text.Replace([客户账户名], "(pty) ltd", "") - 合并以上步骤生成预处理列,对该列做常规分组,最后取原始名称中出现次数最多的作为标准化名称
内容的提问来源于stack exchange,提问作者Yardleigh Anthony
相关产品推荐
相关产品推荐

