Power Query M - 使用自定义聚合按列值分组(百分位数)
Power Query M - Group by Column Value with Custom Aggregation (Percentile)
我正在尝试在 power 查询中按组计算百分位数(根据列值,例如:按部门的小时数、按地区的销售额等)。同样的逻辑可用于其他自定义组聚合。经过大量搜索,我发现了 2 种可能的方法。
方法一:
this archived article 看起来有完美的答案。我找不到其他任何东西可以接近。
那里的解决方案是以下自定义函数:
//PercentileInclusive Function
(inputSeries as list, percentile as number) =>
let
SeriesCount = List.Count(inputSeries),
PercentileRank = percentile * (SeriesCount - 1) + 1, //percentile value between 0 and 1
PercentileRankRoundedUp = Number.RoundUp(PercentileRank),
PercentileRankRoundedDown = Number.RoundDown(PercentileRank),
Percentile1 = List.Max(List.MinN(inputSeries, PercentileRankRoundedDown)),
Percentile2 = List.Max(List.MinN(inputSeries, PercentileRankRoundedUp)),
PercentileInclusive = Percentile1 + (Percentile2 - Percentile1) * (PercentileRank - PercentileRankRoundedDown)
in
PercentileInclusive
结合 table 中的一个步骤进行适当分组并使用函数:
=Table.Group(TableName, {"Grouping Column"}, {{"New Column name", each
PercentileInclusive(TableName[Column to calculate Percentile of], percentile # between 0 and 1)}})
[编辑以更正 Ron R. 指出的错字并删除不必要的细节]
示例输入:
Pen Type
Units Sold
Ball-Point
6,109
Ball-Point
3,085
Ball-Point
1,970
Ball-Point
8,190
Ball-Point
6,006
Ball-Point
2,671
Ball-Point
6,875
Roller
778
Roller
9,329
Roller
7,781
Roller
4,182
Roller
2,016
Roller
5,785
Roller
1,411
按笔类型分组的 25%(含)百分比的所需输出:
Pen Type
0.25 Inclusive Percentile (Correct)
Ball-Point
2,878
Roller
1,714
注意:上面没有显示小数,用 Excel 的 PERCENTILE.INC 函数计算。
方法 1 效果很好。
方法二:
这是我尝试过的替代 Power Query 解决方案。这是一个没有自定义功能的单步操作。看起来应该可以解决问题,但我想不出一种方法来使条件检查成为基于行的。有些东西需要去我有 //Condition// 的地方告诉它哪些行属于当前行组,但无论我尝试什么它都不起作用。它要么中断,要么给出所有内容的百分位数,忽略分组。
=List.Percentile(Table.Column(Table.SelectRows(#"Previous Step Name", //Condition//), "Column to calculate percentile of"), percentile # 0 to 1)
关于如何使方法 2 起作用的任何想法?
您的 Table.Group
函数似乎指定不正确。
我之前的步骤是 #"Changed Type"
,以下是有效的:
#"Grouped Rows" = Table.Group(#"Changed Type", {"Pen Type"}, {
{"Percentile", each fnPercentileINC([Units Sold],0.25)}})
原始数据
M代码
let
Source = Excel.CurrentWorkbook(){[Name="Table4"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Pen Type", type text}, {"Units Sold", Int64.Type}}),
#"Grouped Rows" = Table.Group(#"Changed Type", {"Pen Type"}, {
{"Percentile", each fnPercentileINC([Units Sold],0.25), type number}})
in
#"Grouped Rows"
结果
编辑:
对于方法 #2,如果没有自定义函数,您只能使用 List.Percentile
作为 Table.Group
函数中的聚合:
#"Grouped Rows" = Table.Group(#"Changed Type", {"Pen Type"}, {
{"25th Percentile", each List.Percentile([Units Sold],0.25)}
})
我正在尝试在 power 查询中按组计算百分位数(根据列值,例如:按部门的小时数、按地区的销售额等)。同样的逻辑可用于其他自定义组聚合。经过大量搜索,我发现了 2 种可能的方法。
方法一:
this archived article 看起来有完美的答案。我找不到其他任何东西可以接近。
那里的解决方案是以下自定义函数:
//PercentileInclusive Function
(inputSeries as list, percentile as number) =>
let
SeriesCount = List.Count(inputSeries),
PercentileRank = percentile * (SeriesCount - 1) + 1, //percentile value between 0 and 1
PercentileRankRoundedUp = Number.RoundUp(PercentileRank),
PercentileRankRoundedDown = Number.RoundDown(PercentileRank),
Percentile1 = List.Max(List.MinN(inputSeries, PercentileRankRoundedDown)),
Percentile2 = List.Max(List.MinN(inputSeries, PercentileRankRoundedUp)),
PercentileInclusive = Percentile1 + (Percentile2 - Percentile1) * (PercentileRank - PercentileRankRoundedDown)
in
PercentileInclusive
结合 table 中的一个步骤进行适当分组并使用函数:
=Table.Group(TableName, {"Grouping Column"}, {{"New Column name", each
PercentileInclusive(TableName[Column to calculate Percentile of], percentile # between 0 and 1)}})
[编辑以更正 Ron R. 指出的错字并删除不必要的细节]
示例输入:
Pen Type | Units Sold |
---|---|
Ball-Point | 6,109 |
Ball-Point | 3,085 |
Ball-Point | 1,970 |
Ball-Point | 8,190 |
Ball-Point | 6,006 |
Ball-Point | 2,671 |
Ball-Point | 6,875 |
Roller | 778 |
Roller | 9,329 |
Roller | 7,781 |
Roller | 4,182 |
Roller | 2,016 |
Roller | 5,785 |
Roller | 1,411 |
按笔类型分组的 25%(含)百分比的所需输出:
Pen Type | 0.25 Inclusive Percentile (Correct) |
---|---|
Ball-Point | 2,878 |
Roller | 1,714 |
注意:上面没有显示小数,用 Excel 的 PERCENTILE.INC 函数计算。
方法 1 效果很好。
方法二: 这是我尝试过的替代 Power Query 解决方案。这是一个没有自定义功能的单步操作。看起来应该可以解决问题,但我想不出一种方法来使条件检查成为基于行的。有些东西需要去我有 //Condition// 的地方告诉它哪些行属于当前行组,但无论我尝试什么它都不起作用。它要么中断,要么给出所有内容的百分位数,忽略分组。
=List.Percentile(Table.Column(Table.SelectRows(#"Previous Step Name", //Condition//), "Column to calculate percentile of"), percentile # 0 to 1)
关于如何使方法 2 起作用的任何想法?
您的 Table.Group
函数似乎指定不正确。
我之前的步骤是 #"Changed Type"
,以下是有效的:
#"Grouped Rows" = Table.Group(#"Changed Type", {"Pen Type"}, {
{"Percentile", each fnPercentileINC([Units Sold],0.25)}})
原始数据
M代码
let
Source = Excel.CurrentWorkbook(){[Name="Table4"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Pen Type", type text}, {"Units Sold", Int64.Type}}),
#"Grouped Rows" = Table.Group(#"Changed Type", {"Pen Type"}, {
{"Percentile", each fnPercentileINC([Units Sold],0.25), type number}})
in
#"Grouped Rows"
结果
编辑:
对于方法 #2,如果没有自定义函数,您只能使用 List.Percentile
作为 Table.Group
函数中的聚合:
#"Grouped Rows" = Table.Group(#"Changed Type", {"Pen Type"}, {
{"25th Percentile", each List.Percentile([Units Sold],0.25)}
})