英文:
Discrete time Integral of a value in Power Query
问题
我有一个名为CA-27的Excel表格,是从Power Query脚本加载的。
CA-27包含一个名为Q的decimal类型列,表示流量。它还包含一个名为Time的time类型列,其中包含了YYYY-MM-DD hh:mm:ss格式的日期数据。
我需要在Power Query中运行一个额外的步骤,以添加一个名为V的列,其中包含累积体积值。我需要一个公式来计算Q在Time上的离散积分,以创建列V。该公式需要实现离散积分的梯形法则。
我知道如何直接在Excel单元格中编写公式来实现离散积分,但我想在Power Query中创建累积体积,以便可以使用相同的Power Query步骤处理其他数据。
注意:假设先前用于查询CA-27的最后一步被称为previousStep。
我首先尝试了以下M语言语法来在Power Query中创建列V:
List.Accumulate(#"previousStep"[Q], 0, (state, current) => state + current * Duration.TotalSeconds([# "CA-27.Time"] - List.First(# "previousStep"[# "CA-27.Time"])))
我期望得到累积体积,但我收到了以下错误消息:"Expression.Error: There is an unknown identifier"。
然后我尝试了这个替代的M语言语法:
let
Source = previousStep,
Integrated = List.Accumulate(Source[Q], 0, (state, current) =>
state + current * Duration.TotalSeconds([CA-27.Time] - List.First(Source[CA-27.Time]))
)
in
Integrated
这个替代语法收到了以下错误消息:"Expression.SyntaxError: Token Comma expected"
梯形法则用于离散积分:
第一行数据,索引为(k-1),没有定义Delta_T和V,因此V=0。对于从第二行开始的行,范围(k) = [2:N],计算如下:
Delta_T(k) = [Time(k) - Time(k-1)]; \ (单位为秒)
V(k) = 0.5 * [Q(k) + Q(k-1)] * Delta_T(k); \ (单位为立方米)
我根据@horseyride的建议编辑了M语言代码如下:
let
Source = #"Renamed Time",
//偏移1行
MinusOne = #table({"Column1"}, {{null}}) & Table.Skip(Table.DemoteHeaders(Table.RemoveLastN(#"Renamed Time",1)),1),
custom1 = Table.ToColumns(#"Renamed Time") & Table.ToColumns(MinusOne ),
custom2 = Table.FromColumns(custom1,Table.ColumnNames(#"Renamed Time")&List.Transform(Table.ColumnNames(#"Renamed Time"), each _&"prior")),
#"Added Custom" = Table.AddColumn(custom2, "Custom", each Duration.TotalSeconds([Time]-[Timeprior])*.5*([Qg_dh]+[Qg_dhprior])),
#"Added Index" = Table.AddIndexColumn(#"Added Custom", "IndexDT", 0, 1, Int64.Type),
#"Added Cum Total" = Table.AddColumn(#"Added Index", "Vg_dh", each List.Sum(List.FirstN(#"Added Index"[Custom],[IndexDT]+1))),
#"Removed Columns" = Table.RemoveColumns(#"Added Cum Total",{"Timeprior", "Qg_dhprior", "Custom", "IndexDT"})
in #"Removed Columns"
然而,根据Rename Time步骤之后的此附加查询步骤进行处理似乎导致了一个无限循环,或者至少是对一个简单累积结果的异常长时间处理。
等待了几分钟后,我得到了以下错误消息:
"Expression.Error: Evaluation ran out of memory and can't continue."
英文:
I have an Excel table named CA-27 loaded from an Power Query script.
CA-27 contains a decimal type column named Q, representing a flow rate. It also contains a time type column named Time with YYYY-MM-DD hh:mm:ss data.
I need to run an additional step in Power Query to add a column named V with cumulative volume values. I need a formula to calculate a discrete integral of Q over Time to create column V. The formula needs to implement the trapezoidal method for discrete integration.
I know how to write formulas directly in excel cells to implement the discrete integration but I want to create the cumulative volume within Power Query, so I can process additional data using the same Power Query steps.
NOTE: Assume the last step previously used to query CA-27 is called previousStep.
I first tried the following M-language syntax to create column V within Power Query:
List.Accumulate(#"previousStep"[Q], 0,(state, current) => state + current Duration.TotalSeconds([#"CA-27.Time"] - List.First(#"previousStep"[#"CA-27.Time"])))
I expected to get the cumulative volume but I got the following error message: "Expression.Error: There is an unknown identifier".
Then I tried this alternative M-language sytnax:
let
Source = previousStep, Integrated = List.Accumulate(Source[Q],0,(state, current) =>
state + current * Duration.TotalSeconds([CA-27.Time] - List.First(Source[CA-27.Time]))
)
in
Integrated
This alternatuve syntax got the following error message: "Expression.SyntaxError: Token Comma expected"
Trapezoid rule for discrete integrals:
The first data row, index=(k-1), has no defined Delta_T and V=0.
For the second row onward, range(k) = [2:N], calculations are defined as:
Delta_T(k) = [Time(k) - Time(k-1)]; \\ (unit is seconds)
V(k) = 0.5 * [Q(k) + Q(k-1)] * Delta_T(k); \\ (unit is cubic meters)
I've edited the M language code per @horseyride's suggestions as follows:
= let Source = #"Renamed Time",
//offset by 1 row
MinusOne = #table({"Column1"}, {{null}}) & Table.Skip(Table.DemoteHeaders(Table.RemoveLastN(#"Renamed Time",1)),1),
custom1 = Table.ToColumns(#"Renamed Time") & Table.ToColumns(MinusOne ),
custom2 = Table.FromColumns(custom1,Table.ColumnNames(#"Renamed Time")&List.Transform(Table.ColumnNames(#"Renamed Time"), each _&"prior")),
#"Added Custom" = Table.AddColumn(custom2, "Custom", each Duration.TotalSeconds([Time]-[Timeprior])*.5*([Qg_dh]+[Qg_dhprior])),
#"Added Index" = Table.AddIndexColumn(#"Added Custom", "IndexDT", 0, 1, Int64.Type),
#"Added Cum Total" = Table.AddColumn(#"Added Index", "Vg_dh", each List.Sum(List.FirstN(#"Added Index"[Custom],[IndexDT]+1))),
#"Removed Columns" = Table.RemoveColumns(#"Added Cum Total",{"Timeprior", "Qg_dhprior", "Custom", "IndexDT"})
in #"Removed Columns"
However, processing per this additional query step following the Rename Time step appears to result in an infinite loop, or at least an unusually long processing time for a simple cumulative result.
After waiting several minutes I got this error message:
> Expression.Error: Evaluation ran out of memory and can't continue.
答案1
得分: 0
你需要以数字形式发布样本数据,而不是图像。
也就是说,请尝试:
let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Time", type datetime}}),
// 偏移1行
MinusOne = #table({"Column1"}, {{null}}) & Table.Skip(Table.DemoteHeaders(Table.RemoveLastN(#"Changed Type",1)),1),
custom1 = Table.ToColumns(#"Changed Type") & Table.ToColumns(MinusOne ),
custom2 = Table.FromColumns(custom1,Table.ColumnNames(#"Changed Type")&List.Transform(Table.ColumnNames(#"Changed Type"), each _&"prior")),
#"Added Custom" = Table.AddColumn(custom2, "Custom", each Duration.TotalSeconds([Time]-[Timeprior])*.5*([Q]+[Qprior])),
#"Added Index" = Table.AddIndexColumn(#"Added Custom", "Index", 0, 1, Int64.Type),
#"Added Cum Total" = Table.AddColumn(#"Added Index", "V", each List.Sum(List.FirstN(#"Added Index"[Custom],[Index]+1))),
#"Removed Columns" = Table.RemoveColumns(#"Added Cum Total",{"Timeprior", "Qprior", "Custom", "Index"}),
#"Changed Type2" = Table.TransformColumnTypes(#"Removed Columns",{{"Time", type datetime}})
in #"Changed Type2"
英文:
You need to post sample data as numbers, not images
That said, try
let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Time", type datetime}}),
//offset by 1 row
MinusOne = #table({"Column1"}, {{null}}) & Table.Skip(Table.DemoteHeaders(Table.RemoveLastN(#"Changed Type",1)),1),
custom1 = Table.ToColumns(#"Changed Type") & Table.ToColumns(MinusOne ),
custom2 = Table.FromColumns(custom1,Table.ColumnNames(#"Changed Type")&List.Transform(Table.ColumnNames(#"Changed Type"), each _&"prior")),
#"Added Custom" = Table.AddColumn(custom2, "Custom", each Duration.TotalSeconds([Time]-[Timeprior])*.5*([Q]+[Qprior])),
#"Added Index" = Table.AddIndexColumn(#"Added Custom", "Index", 0, 1, Int64.Type),
#"Added Cum Total" = Table.AddColumn(#"Added Index", "V", each List.Sum(List.FirstN(#"Added Index"[Custom],[Index]+1))),
#"Removed Columns" = Table.RemoveColumns(#"Added Cum Total",{"Timeprior", "Qprior", "Custom", "Index"}),
#"Changed Type2" = Table.TransformColumnTypes(#"Removed Columns",{{"Time", type datetime}})
in #"Changed Type2"
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论