Power Query - 具有性能问题的 COUNTIFS 模仿者。哪种方法更好?
Power Query - COUNTIFS copycat with performance issue. Which is a better approach?
场景和数据结构很简单
我有一个清单,其中包含产品代码和该产品的零售月份。可以在下图中的前两列绿色部分看到此类数据的示例。
然后我需要检查每个产品是否也在上个月、过去 3 个月或过去 12 个月内零售过。结果将是图像上接下来的三列黄色。
这些计算(黄色列)很容易在 Excel 处使用一些 IF 和 COUNTIFS 公式计算,但是当将其迁移到 Power BI 时,我在 Power Query 中遇到代码性能问题.由于每个月有数千种产品,Power Query 计算时间过长。
检查下面我设计的代码。代码快照将用于第二个黄色列,以告知该产品在过去 3 个月是否有零售。
本质上,我正在做的是添加一个计算列,该列计算 table 的行数,该列使用产品代码信息和相关日期进行过滤。
在性能方面获取所需信息的更好方法是什么?
谢谢。
代码:
// Add a calculated column.
AdicionarHits03Meses = Table.AddColumn(
AdicionarHits01Mes,
"Hit nos últimos 3 meses?",
(r)=>
// Check if...
if
// Returns the rows count of a table.
Table.RowCount(
// Returns a table with the condition.
Table.SelectRows(
ChangeType,
// Condition:
(q)=>
// Same Product Code.
q[#"Product Code"] = r[#"Product Code"]
and
// Check the retail month.
q[#"Retail month"] <= Date.AddMonths(r[#"Retail month"], -1) and
q[#"Retail month"] >= Date.AddMonths(r[#"Retail month"], -3)
)
)
= 0 then
// No retail found.
0 else
// Retail found.
1
,
Int64.Type
)
您可以通过一些巧妙的自合并来提高性能。
看看这对你是否有意义:
let
Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WMlTSUfJKzFMwMjAyVIrViVYyQhcwRhcAaXFLTUIV8E0sQjXDN7ESzdDSHKhALAA=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [#"Product Code" = _t, #"Retail Month" = _t]),
Original = Table.TransformColumnTypes(Source,{{"Product Code", Int64.Type}, {"Retail Month", type date}}),
#"Added Offset Lists" = Table.AddColumn(Original, "Offset", each {1..12}),
#"Expanded Offset Column" = Table.ExpandListColumn(#"Added Offset Lists", "Offset"),
#"Added Prev Column" = Table.AddColumn(#"Expanded Offset Column", "Prev", each Date.AddMonths([Retail Month], -[Offset] ), type date),
#"Inner Join Prev to Original" = Table.NestedJoin(#"Added Prev Column", {"Product Code", "Prev"}, Original, {"Product Code", "Retail Month"}, "Retail", JoinKind.Inner),
#"Merge Original to Prev" = Table.NestedJoin(Original, {"Product Code", "Retail Month"}, #"Inner Join Prev to Original", {"Product Code", "Retail Month"}, "Min Offset", JoinKind.LeftOuter),
#"Expanded Min Offset" = Table.TransformColumns(#"Merge Original to Prev", {{"Min Offset", each List.Min([Offset]), Int64.Type}}),
#"Added Last Month" = Table.AddColumn(#"Expanded Min Offset", "Retail last month", each if [Min Offset] = 1 then "Yes" else "No", type text),
#"Added Last 3 Months" = Table.AddColumn(#"Added Last Month", "Retailed since last 3 months", each if [Min Offset] <> null and [Min Offset] <= 3 then "Yes" else "No", type text),
#"Added Last 12 Months" = Table.AddColumn(#"Added Last 3 Months", "Retailed since 12 months", each if [Min Offset] <> null and [Min Offset] <= 12 then "Yes" else "No", type text)
in
#"Added Last 12 Months"
我没有时间详细解释但大纲大致如下:
- 将每行扩展到前几个月的 12 行。
- 将之前的月份与原始 table 中的行相匹配。
- 将原始行与为该行找到的所有匹配项合并。
- 为每个匹配集找到最近的匹配(最小偏移)。
- 使用此偏移量定义 1、3 和 12 个月的回顾列。
场景和数据结构很简单
我有一个清单,其中包含产品代码和该产品的零售月份。可以在下图中的前两列绿色部分看到此类数据的示例。
然后我需要检查每个产品是否也在上个月、过去 3 个月或过去 12 个月内零售过。结果将是图像上接下来的三列黄色。
这些计算(黄色列)很容易在 Excel 处使用一些 IF 和 COUNTIFS 公式计算,但是当将其迁移到 Power BI 时,我在 Power Query 中遇到代码性能问题.由于每个月有数千种产品,Power Query 计算时间过长。
检查下面我设计的代码。代码快照将用于第二个黄色列,以告知该产品在过去 3 个月是否有零售。
本质上,我正在做的是添加一个计算列,该列计算 table 的行数,该列使用产品代码信息和相关日期进行过滤。
在性能方面获取所需信息的更好方法是什么?
谢谢。
代码:
// Add a calculated column.
AdicionarHits03Meses = Table.AddColumn(
AdicionarHits01Mes,
"Hit nos últimos 3 meses?",
(r)=>
// Check if...
if
// Returns the rows count of a table.
Table.RowCount(
// Returns a table with the condition.
Table.SelectRows(
ChangeType,
// Condition:
(q)=>
// Same Product Code.
q[#"Product Code"] = r[#"Product Code"]
and
// Check the retail month.
q[#"Retail month"] <= Date.AddMonths(r[#"Retail month"], -1) and
q[#"Retail month"] >= Date.AddMonths(r[#"Retail month"], -3)
)
)
= 0 then
// No retail found.
0 else
// Retail found.
1
,
Int64.Type
)
您可以通过一些巧妙的自合并来提高性能。
看看这对你是否有意义:
let
Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WMlTSUfJKzFMwMjAyVIrViVYyQhcwRhcAaXFLTUIV8E0sQjXDN7ESzdDSHKhALAA=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [#"Product Code" = _t, #"Retail Month" = _t]),
Original = Table.TransformColumnTypes(Source,{{"Product Code", Int64.Type}, {"Retail Month", type date}}),
#"Added Offset Lists" = Table.AddColumn(Original, "Offset", each {1..12}),
#"Expanded Offset Column" = Table.ExpandListColumn(#"Added Offset Lists", "Offset"),
#"Added Prev Column" = Table.AddColumn(#"Expanded Offset Column", "Prev", each Date.AddMonths([Retail Month], -[Offset] ), type date),
#"Inner Join Prev to Original" = Table.NestedJoin(#"Added Prev Column", {"Product Code", "Prev"}, Original, {"Product Code", "Retail Month"}, "Retail", JoinKind.Inner),
#"Merge Original to Prev" = Table.NestedJoin(Original, {"Product Code", "Retail Month"}, #"Inner Join Prev to Original", {"Product Code", "Retail Month"}, "Min Offset", JoinKind.LeftOuter),
#"Expanded Min Offset" = Table.TransformColumns(#"Merge Original to Prev", {{"Min Offset", each List.Min([Offset]), Int64.Type}}),
#"Added Last Month" = Table.AddColumn(#"Expanded Min Offset", "Retail last month", each if [Min Offset] = 1 then "Yes" else "No", type text),
#"Added Last 3 Months" = Table.AddColumn(#"Added Last Month", "Retailed since last 3 months", each if [Min Offset] <> null and [Min Offset] <= 3 then "Yes" else "No", type text),
#"Added Last 12 Months" = Table.AddColumn(#"Added Last 3 Months", "Retailed since 12 months", each if [Min Offset] <> null and [Min Offset] <= 12 then "Yes" else "No", type text)
in
#"Added Last 12 Months"
我没有时间详细解释但大纲大致如下:
- 将每行扩展到前几个月的 12 行。
- 将之前的月份与原始 table 中的行相匹配。
- 将原始行与为该行找到的所有匹配项合并。
- 为每个匹配集找到最近的匹配(最小偏移)。
- 使用此偏移量定义 1、3 和 12 个月的回顾列。