对Pentaho中的缺失值进行插值

时间:2019-05-04 05:04:29

标签: pentaho pentaho-spoon pentaho-data-integration

我正在尝试使用Pentaho pdi填写缺少的值。

输入:

enter image description here

所需的输出:

enter image description here

迄今仅发现Filling data gaps in a stream in Pentaho Data Integration, is it possible?,但使用最后一个已知值进行填充。

可能的是,我认为我可以使用上述解决方案,我还向分析查询中添加了下一个金额以及下一个日期。然后,我在克隆步骤中添加了该标志,并将输入的原始结果过滤到Dummy中,并将生成的结果(从计算器)过滤到计算器(此刻)。然后,潜在地,我可以将该单独的流转储到数据库中的temp表中,并运行sql查询,该查询将进行滚动减法。我也在调查javascript步骤。

我忽略了Python或R Executor步骤,因为最后我将在aws vm上运行该作业,并且我已经预见到安装过程将经历的痛苦。

您有什么建议?有简单的插值方法吗?

已更新问题 enter image description here

enter image description here

1 个答案:

答案 0 :(得分:1)

您的链接中提供的方法在我的测试中确实有效(不过,我使用LAG而不是LEAD来完成您的任务)。在这里,我不打算复制该方法,而只是通过使用JavaScript构建可以扩展到其他应用程序的逻辑的另一种选择:

在下面的测试中(在PDI-8.0上测试),转换过程分为5个步骤,请参见下文

enter image description here

  1. 数据网格步骤创建包含三个字段的测试数据:dateaccount numberamount
  2. 对行进行排序,以根据account numberdate对行进行排序。 Analytic Query步骤需要执行此操作,如果您的源数据已经排序,请跳过此步骤
  3. 分析查询步骤(请参见下文),再创建两个字段:prev_dateprev_amount

enter image description here

  1. 修改后的Java脚本值步骤,添加以下代码,在此步骤中无需进行其他配置:

    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

更新:

根据您的评论,假设您有一个新字段account_type,您可以执行以下操作:

  1. Analytic Query 步骤中,添加一个新字段prev_account_type,类似于其他两个prev_字段,只是来自不同的Subject account_type

  2. Modified Java Script Value (修改的Java脚本值)步骤中,您需要检索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);
        } 
    }
    

注意::调用Java解释器确实会对性能产生影响,因此,如果对您而言很重要,请坚持使用您提供的链接中的方法。