Страницы: 1
RSS
Power Query: Как максимально ускорить расчет
 
Всем привет !

Данный запрос очень медленно обрабатывает информацию из исходника (~2к строк за 15 мин, при 500к+ строках ждать придется очень долго)
Запрос рассчитывает расстояние между двумя точками с географическими координатами с последующим расчетом скорости, поскольку в исходной выгрузку скорость дана криво
Может есть способ ускорить расчет?

Код:
Код
let
    Source = Csv.Document(File.Contents("C:............csv"),[Delimiter=";", Columns=4, Encoding=1251, QuoteStyle=QuoteStyle.None]),
    #"Promoted Headers" = Table.PromoteHeaders(Source),
    #"Changed Type" = Table.TransformColumnTypes(#"Promoted Headers",{{"CarNumber", Int64.Type}, {"DateTime", type datetime}, {"GPS", type text}, {"Speed", type number}}),
    #"Split Column by Delimiter" = Table.SplitColumn(#"Changed Type","GPS",Splitter.SplitTextByDelimiter(":", QuoteStyle.Csv),{"GPS.1", "GPS.2"}),
    #"Changed Type1" = Table.TransformColumnTypes(#"Split Column by Delimiter",{{"GPS.1", type number}, {"GPS.2", type number}}),
    #"Renamed Columns" = Table.RenameColumns(#"Changed Type1",{{"GPS.1", "Latitude"}, {"GPS.2", "Longitude"}}),
    AddedIndex = Table.AddIndexColumn(#"Renamed Columns", "Index", -1, 1),
    #"Added Custom" = Table.AddColumn(AddedIndex, "Time", each if [Index]=-1 then null else Duration.Seconds([DateTime]-AddedIndex{[Index]}[DateTime])),
    #"Changed Type2" = Table.TransformColumnTypes(#"Added Custom",{{"Time", Int64.Type}}),
    a = Table.AddColumn(#"Changed Type2", "a", each if [Index]=-1 then null else Number.Sin(Number.Power(([Latitude]*Number.PI/180-AddedIndex{[Index]}[Latitude]*Number.PI/180)/2,2))+Number.Cos([Latitude]*Number.PI/180)*Number.Cos(AddedIndex{[Index]}[Latitude]*Number.PI/180)*Number.Sin(Number.Power(([Longitude]*Number.PI/180-AddedIndex{[Index]}[Longitude]*Number.PI/180)/2,2))),
    #"Distance calculation" = Table.AddColumn(a, "Distance", each 2*Number.Atan2(Number.Sqrt([a]),Number.Sqrt(1-[a]))*6371000),
    #"Changed Type3" = Table.TransformColumnTypes(#"Distance calculation",{{"Distance", type number}}),
    #"Speed calculation" = Table.AddColumn(#"Changed Type3", "Speed, km/h", each if [Time]=null then null else [Distance]*3.6/[Time]),
    #"Removed Columns" = Table.RemoveColumns(#"Speed calculation",{"Index", "Time", "a", "Distance"})
in
    #"Removed Columns"

Спасибо!
 
Для понимания, в столбце а реализуется формула Хаверсина:
 
Вы используете крайне ресурсозатратный механизм обращения к предыдущей строке. Посмотрите вот эту тему. Я там давал ссылки и готовую функцию как это делать с оптимальной скоростью.
Вот горшок пустой, он предмет простой...
 
PooHkrd, спасибо! Но разобраться действительно сложно, относительно новичок в PQ:)
Как это будет выглядеть на примере?
 
CainV, чего-то не нашел я в примере столбца GPS...
Код
let
    Source = Table.PromoteHeaders(Csv.Document(File.Contents("D:\temp\пример.csv"),[Delimiter=";", Columns=5, Encoding=1251, QuoteStyle=QuoteStyle.None])),
    Typed  = Table.Buffer(Table.TransformColumnTypes(Source,{{"CarNumber", Int64.Type},{"DateTime", type datetime}, {"Latitude", type number}, {"Longitude", type number}, {"Speed", type number}})),
    Rad    = (a) => a*Number.PI/180,
    Hav    = (a) => Number.Sin(Number.Power(a/2,2)),
    Dist   = (h) => 2*Number.Atan2(Number.Sqrt(h),Number.Sqrt(1-h))*6371000,
    Speed  = (φ1,φ2,λ1,λ2,t1,t2)=> Dist(Hav(φ2-φ1)+Number.Cos(φ1)*Number.Cos(φ2)*Hav(λ2-λ1))*3.6/Duration.TotalSeconds(t2-t1),
    Custom1 = Table.FromRecords(
        List.Generate(()=>
            [i=0,r=Typed{i},t=r[DateTime],φ=Rad(r[Latitude]),λ=Rad(r[Longitude]),speed=null],
            each [i]<Table.RowCount(Typed),
            each [i=[i]+1,r=Typed{i},t=r[DateTime],φ=Rad(r[Latitude]),λ=Rad(r[Longitude]),speed=Speed([φ],φ,[λ],λ,[t],t)],
            each Record.AddField([r],"Speed, km/h",[speed])
        )
    )
in
    Custom1
Страницы: 1
Наверх