Power Query Excel 将值显示为列的百分比

Posted

技术标签:

【中文标题】Power Query Excel 将值显示为列的百分比【英文标题】:Power Query Excel show values as percentage of column 【发布时间】:2017-11-01 13:29:58 【问题描述】:

通常,数据透视表用于按特定顺序呈现数据。对于这个特定的“问题”,我需要提供数字和目标。 这与 Pivots 中的冲突,因为列的百分比也考虑了目标。

不用担心,使用 PowerPivot 应该可以解决这个问题。到目前为止,我已经能够创建一个具有以下布局的表格:

         1     2    3
cat A    5    10    7
cat B    10    8    9
cat C    0     2    1

其中 1、2 和 3 是一个月的前三天(为简单起见,省略了休息)。

我可以得到如下列的总数:

= Table.FromRows(List.Transform("1","2","3", each List.Sum(Table.Column(prevStep, _))), "1","2","3")

此外,我可以将列的每个值除以一个数字:

= Table.TransformColumns(prevStep, List.Transform("1","2","3", each _, (this) =>  this / 42, type number))

现在我想用之前为列计算的总数替换 42。请注意,""1","2","3"" 将在另一个步骤中自动计算。

有人可以详细说明如何实现这一目标吗?预期结果:

         1     2    3
cat A    0.33  0.5    0.41
cat B    0.67  0.4    0.53
cat C    0     0.1    0.06

【问题讨论】:

【参考方案1】:

我无法想出一种方法来简单地替换代码中的 42,但由于我看到这是矩阵数学,因此我基于 Gil Raviv's blog on matrix multiplication 为您的问题提供了以下解决方案。

我从 Table1 开始:

那么,到这里来……

...我使用 Table1 作为新查询的源,这段代码:

let
    Source = Table1,
    #"Removed Columns" = Table.RemoveColumns(Source,""),
    MatrixA = Table.TransformColumnTypes(#"Removed Columns","1", type number, "2", type number, "3", type number),
    Summed = Table.FromRows(List.Transform("1","2","3", each List.Sum(Table.Column(MatrixA, _))), "1","2","3"),
    MatrixB = Table.TransformColumnTypes(Summed,"1", type number, "2", type number, "3", type number),
    IndexedMatrixA = Table.AddIndexColumn(MatrixA, "Index", 1, 1),
    #"Unpivoted Other Columns" = Table.UnpivotOtherColumns(IndexedMatrixA, "Index", "Attribute", "Value"),
    #"Changed Type" = Table.TransformColumnTypes(#"Unpivoted Other Columns","Attribute", Int64.Type),
    RenamedColumnsMatrixA = Table.RenameColumns(#"Changed Type","Index", "Row", "Attribute", "Column"),
    IndexedMatrixB = Table.AddIndexColumn(MatrixB, "Index", 1, 1),
    #"Unpivoted Other Columns1" = Table.UnpivotOtherColumns(IndexedMatrixB, "Index", "Attribute", "Value"),
    #"Changed Type1" = Table.TransformColumnTypes(#"Unpivoted Other Columns1","Attribute", Int64.Type),
    RenamedColumnsMatrixB = Table.RenameColumns(#"Changed Type1","Index", "Row", "Attribute", "Column"),
    #"Merged Queries" = Table.NestedJoin(RenamedColumnsMatrixA,"Column",RenamedColumnsMatrixB,"Column","RenamedColumnsMatrixB",JoinKind.LeftOuter),
    #"Expanded RenamedColumnsMatrixB" = Table.ExpandTableColumn(#"Merged Queries", "RenamedColumnsMatrixB", "Row", "Column", "Value", "B.Row", "B.Column", "B.Value"),
    #"Added Custom" = Table.AddColumn(#"Expanded RenamedColumnsMatrixB", "AB", each [Value]/[B.Value]),
    #"Grouped Rows" = Table.Group(#"Added Custom", "Row", "B.Column", "AB", each List.Sum([AB]), type number),
    #"Pivoted Column" = Table.Pivot(Table.TransformColumnTypes(#"Grouped Rows", "B.Column", type text, "en-US"), List.Distinct(Table.TransformColumnTypes(#"Grouped Rows", "B.Column", type text, "en-US")[B.Column]), "B.Column", "AB"),
    #"Added Index" = Table.AddIndexColumn(#"Pivoted Column", "Index", 1, 1),
    IndexedSource = Table.AddIndexColumn(Source, "Index", 1, 1),
    #"Merged Queries1" = Table.NestedJoin(#"Added Index","Index",IndexedSource,"Index","IndexedSource",JoinKind.LeftOuter),
    #"Expanded IndexedSource" = Table.ExpandTableColumn(#"Merged Queries1", "IndexedSource", "", "Column1"),
    #"Removed Columns1" = Table.RemoveColumns(#"Expanded IndexedSource","Row", "Index"),
    #"Reordered Columns" = Table.ReorderColumns(#"Removed Columns1","Column1", "1", "2", "3")
in
    #"Reordered Columns"

你会注意到我有点“跳来跳去”,使用以前的应用步骤(基本上是查询表状态)作为代码中的“表”......就像在这些应用步骤中一样:

索引 MatrixB(IndexedMatrixB = Table.AddIndexColumn(MatrixB, "Index", 1, 1), 其中MatrixB 是先前的应用步骤);和

合并查询(#"Merged Queries" = Table.NestedJoin(RenamedColumnsMatrixA,"Column",RenamedColumnsMatrixB,"Column","RenamedColumnsMatrixB",JoinKind.LeftOuter), 其中RenamedColumnsMatrixARenamedColumnsMatrixB 是以前的应用步骤)。

【讨论】:

【参考方案2】:

@Marc Pince;谢谢你的建议。经过一番努力,我能够做以下菜:

首先,我将总和计算行换成如下:

totMinDay =  Table.ToRows    (Table.FromRows(List.Transform(daysOfMonth , each List.Sum(Table.Column(prevStep, _))), daysOfMonth ))0,

其中 daysOfMonth 是在其他地方获得的实际月份的天数。

接下来我计算百分比如下:

perc= Table.TransformColumns(prevStep, List.Transform(daysOfMonth , each _, (this) =>  Number.Round(this/ ( totMinDay Number.FromText( _ ) - 1 ), 3), type number)),

这里我使用了这样一个事实,即总和的索引基于月份中的某天减去 1(从零开始),从而提供可靠的结果。

感谢所有输入。

【讨论】:

好简洁的解决方案!【参考方案3】:

在这种情况下,您可以使用以下结构访问列名称:Table.Column(TableName, ColumnName)。

在您的示例中,它将是:Table.Column(prevStep, _),其中“_”访问每一列。

所以,你的代码应该是这样的:

= Table.FromRows(List.Transform("1","2","3", each List.Sum(Table.Column(prevStep, _))), "1","2","3")
= Table.TransformColumns(prevStep, List.Transform("1","2","3", each _, (this) =>  this / Table.Column(prevStep, _), type number))

【讨论】:

以上是关于Power Query Excel 将值显示为列的百分比的主要内容,如果未能解决你的问题,请参考以下文章

如何将总行添加到excel power query?

Excel Power Query:将参数传递给 oDataFeed URL 会引发错误

通过 Power Query 在 Excel 中的 Smartsheet 数据

Excel Power Query:工序产出数据的整合与提取

Excel Power Query 拆分表格顶部/底部 50%

M Power Query - 通过将值与两个参考列进行比较,有条件地转换动态列数中的值