Поделиться через


Function.ScalarVector

Синтаксис

Function.ScalarVector(scalarFunctionType as type, vectorFunction as function) as function

О нас

Возвращает скалярную функцию типа scalarFunctionType, которая вызывает vectorFunction с одной строкой аргументов и возвращает его единый вывод. Кроме того, при многократном применении скалярной функции для каждой строки входных данных, например в Table.AddColumn, вместо этого vectorFunction будет применяться один раз для всех входных данных.

vectorFunction будет передана таблица, столбцы которой соответствуют по имени и позиции параметрам scalarFunctionType. Каждая строка этой таблицы содержит аргументы для одного вызова скалярной функции с столбцами, соответствующими параметрам scalarFunctionType.

vectorFunction должен возвращать список той же длины, что и входная таблица, элемент которой в каждой позиции должен совпадать с результатом оценки скалярной функции во входной строке той же позиции.

Предполагается потоковая передача входной таблицы, поэтому vectorFunction должен передавать свои выходные данные по мере поступления входных данных, обрабатывая одновременно только один блок входных данных. В частности, vectorFunction не должно перечислять входную таблицу более одного раза.

Пример 1

Умножайте два столбца входной таблицы, обрабатывая входные данные в пакетах 100.

Использование

let
    Compute.ScoreScalar = (left, right) => left * right,
    // When Function.ScalarVector batching kicks in, we'll receive all
    // of the inputs for the entire table here at once.
    Compute.ScoreVector = (input) => let
        chunks = Table.Split(input, 100),
        scoreChunk = (chunk) => Table.TransformRows(chunk, each Compute.ScoreScalar([left], [right]))
      in
        List.Combine(List.Transform(chunks, scoreChunk)),
    Compute.Score = Function.ScalarVector(
        type function (left as number, right as number) as number, 
        Compute.ScoreVector
    ),
    Final = Table.AddColumn(
        Table.FromRecords({
            [a = 1, b = 2],
            [a = 3, b = 4]
        }),
        "Result",
        each Compute.Score([a], [b])
    )
in
    Final

Выходные данные


Table.FromRecords({
    [a = 1, b = 2, Result = 2],
    [a = 3, b = 4, Result = 12]
})

Пример 2

Вычисляйте результаты тестов в пакетах по два и заполняйте поле идентификатора пакета, которое можно использовать для проверки, что пакетирование работает как ожидается.

Использование

let
  _GradeTest = (right, total) => Number.Round(right / total, 2),
  _GradeTests = (inputs as table) as list => let
    batches = Table.Split(inputs, 2),
    gradeBatch = (batch as table) as list =>
      let
        batchId = Text.NewGuid()
      in
        Table.TransformRows(batch, each [Grade = _GradeTest([right], [total]), BatchId = batchId])
  in
    List.Combine(List.Transform(batches, gradeBatch)),
  GradeTest = Function.ScalarVector(type function (right as number, total as number) as number, _GradeTests),
  Tests = #table(type table [Test Name = text, Right = number, Total = number],
    {
      {"Quiz 1", 3, 4},
      {"Test 1", 17, 22},
      {"Quiz 2", 10, 10}
    }),
  // To break batching, replace [Right] with {[Right]}{0}.
  TestsWithGrades = Table.AddColumn(Tests, "Grade Info", each GradeTest([Right], [Total]), type record),
  // To verify batching, also expand BatchId.
  Final = Table.ExpandRecordColumn(TestsWithGrades, "Grade Info", {"Grade"})
in
  Final

Выходные данные

#table(
    type table [Test Name = text, Right = number, Total = number, Grade = number],
    {
      {"Quiz 1", 3, 4, 0.75},
      {"Test 1", 17, 22, 0.77},
      {"Quiz 2", 10, 10, 1}
    }
)