Интерполяция пропущенных значений в Пентахо - PullRequest
0 голосов
/ 04 мая 2019

Я пытаюсь заполнить пропущенные значения, используя Pentaho pdi.

* +1002 * Введите:

enter image description here

Желаемый вывод:

enter image description here

На данный момент найдено только Возможно ли заполнение пробелов в потоке в Pentaho Data Integration? , но оно заполняется последним известным значением.

Потенциально, я думал, что смогу работать с вышеуказанным решением, я также добавил следующую сумму к аналитическому запросу вместе со следующей датой. Затем я добавил флаг на шаге клонирования и отфильтровал исходные результаты ввода в Dummy и сгенерированные результаты (из калькулятора) в калькулятор (в данный момент). Затем, потенциально, я могу вывести этот отдельный поток во временную таблицу в базе данных и выполнить запрос sql, который выполнит скользящее вычитание. Я также исследую шаг javascript.

Я не принял во внимание шаг Python или R Executor, потому что в конце я буду запускать работу на aws vm, и я уже предвидел боль, которую я переживу при установке.

Что бы вы предложили? Есть ли простой способ сделать интерполяцию?

Обновлено по вопросу enter image description here

enter image description here

1 Ответ

1 голос
/ 04 мая 2019

Метод, указанный в вашей ссылке, работает из моего тестирования (хотя я использую LAG вместо LEAD для ваших задач). Здесь я не собираюсь копировать этот метод, просто еще один вариант для вас, используя JavaScript для построения логики, которую вы также можете распространить на другие приложения:

В приведенном ниже тестировании (проверено на PDI-8.0) преобразование состоит из 5 этапов, см. Ниже

enter image description here

  1. Сетка данных шаг для создания данных тестирования с тремя полями: date, account number и amount
  2. Сортировка строк для сортировки строк по account number и date. это необходимо для шага Analytic Query, если исходные данные уже отсортированы, пропустите этот шаг
  3. Аналитический запрос шаг, см. Ниже, создайте еще два поля: prev_date и prev_amount

enter image description here

  1. Изменено значение Java Script шаг, добавьте следующий код, больше ничего не нужно настраивать на этом шаге:

    var days_diff = dateDiff(prev_date, date, "d")
    
    if (days_diff > 0) {
        /* retrieve index for two fields: 'date', 'amount' 
         * and modify their values accordingly
         */
        var idx_date = getInputRowMeta().indexOfValue("date")
        var idx_amount = getInputRowMeta().indexOfValue("amount")
    
        /* amount to increment by each row */
        var delta_amount = (amount - prev_amount)/days_diff
    
        for (var i = 1; i < days_diff; i++) {
            newRow = createRowCopy(getOutputRowMeta().size());
            newRow[idx_date]   = dateAdd(prev_date, "d", i);
            newRow[idx_amount] = prev_amount + delta_amount * i;
            putRow(newRow);
        } 
    }
    
  2. Выберите значения шаг для удаления ненужных полей, то есть: prev_date, prev_amount

Запустите преобразование, на вкладке Preview data шага Modified Java Script Value отобразится следующее:

enter image description here

UPDATE:

В соответствии с вашими комментариями вы можете сделать следующее, предположив, что у вас есть новое поле account_type:

  1. в Аналитический запрос шаг, добавьте новое поле prev_account_type, аналогичное двум другим полям prev_, только из разных Subject: account_type

  2. in Измененное значение Java Script шаг, вам нужно получить индекс строки для account_type и изменить логику для вычисления delta_amount, поэтому, когда prev_account_type не совпадает с текущим account_type, delta_amount равен нулю, см. код ниже:

    var days_diff = dateDiff(prev_date, date, "d")
    
    if (days_diff > 0) {
        /* retrieve index for three fields: 'date', 'amount', 'account_type' */
        var idx_date     = getInputRowMeta().indexOfValue("date")
        var idx_amount   = getInputRowMeta().indexOfValue("amount")
        var idx_act_type = getInputRowMeta().indexOfValue("account_type")
    
        /* amount to increment by each row */
        var delta_amount = prev_account_type.equals(account_type) ? (amount - prev_amount)/days_diff : 0;
    
        /* copy the current Row into newRow and modify fields accordingly */
        for (var i = 1; i < days_diff; i++) {
            newRow = createRowCopy(getOutputRowMeta().size());
            newRow[idx_date]     = dateAdd(prev_date, "d", i);
            newRow[idx_amount]   = prev_amount + delta_amount * i;
            newRow[idx_act_type] = prev_account_type;
            putRow(newRow);
        } 
    }
    

Примечание: вызов интерпретатора Javascript имеет некоторое снижение производительности, поэтому, если это важно для вас, придерживайтесь метода, указанного в предоставленной вами ссылке.

...