Power Query M - 使用自定义聚合(百分位)按列值分组
Posted
技术标签:
【中文标题】Power Query M - 使用自定义聚合(百分位)按列值分组【英文标题】:Power Query M - Group by Column Value with Custom Aggregation (Percentile) 【发布时间】:2021-12-28 20:18:41 【问题描述】:我正在尝试在电源查询中按组计算百分位数(从列值,例如:按部门的小时数、按地区的销售额等)。相同的逻辑可用于其他自定义组聚合。经过大量搜索,我找到了两种可能的方法。
方法一:
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.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%(含 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 起作用?
【问题讨论】:
如果您编辑您的问题以提供您的数据(或代表性数据)示例(作为可以复制/粘贴的文本)带有 那个 数据的所需输出的屏幕截图,以及用于获得这些结果的逻辑,这将有助于帮助您。 【参考方案1】:看来您的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)
)
【讨论】:
感谢您的仔细检查。这确实是我每次检查自己时都会犯的一个愚蠢的错字。我将清理原始问题以供将来参考。关于如何使方法 #2 起作用的任何想法? @plasmas222 查看我的编辑。只需在Table.Group
聚合中直接使用List.Percentile
。
太棒了,谢谢。对于引用此内容的任何人,如果已经有内置函数,请使用第二种方法,并在需要自定义函数时使用第一种方法。以上是关于Power Query M - 使用自定义聚合(百分位)按列值分组的主要内容,如果未能解决你的问题,请参考以下文章
Reporting Services 使用啥类型的对象将多行传递给自定义聚合函数?