Power Query 中的离散时间值积分

huangapple go评论58阅读模式
英文:

Discrete time Integral of a value in Power Query

问题

我有一个名为CA-27的Excel表格,是从Power Query脚本加载的。

CA-27包含一个名为Qdecimal类型列,表示流量。它还包含一个名为Timetime类型列,其中包含了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"

Power Query 中的离散时间值积分

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"

Power Query 中的离散时间值积分

huangapple
  • 本文由 发表于 2023年7月14日 01:07:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/76681793.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定