【问题标题】:Complete time-series with sparklyr使用 sparklyr 完成时间序列
【发布时间】:2018-09-27 01:20:25
【问题描述】:

我正在尝试在我的时间序列数据集中查找丢失的分钟数。我为一个小样本的本地性能写了一个 R 代码:

test <- dfv %>% mutate(timestamp = as.POSIXct(DaySecFrom.UTC.)) %>% 
complete(timestamp = seq.POSIXt(min(timestamp), max(timestamp), by = 'min'), ElemUID)

但是您不能在 spark_tbl 上使用来自 tidyrcomplete()

Error in UseMethod("complete_") : 
  no applicable method for 'complete_' applied to an object of class "c('tbl_spark', 'tbl_sql', 'tbl_lazy', 'tbl')"

这是一些测试数据:

ElemUID ElemName    Kind    Number  DaySecFrom(UTC) DaySecTo(UTC)
399126817   A648/13FKO-66   DEZ     2017-07-01 23:58:00.000 2017-07-01 23:59:00.000
483492732   A661/18FRS-97   DEZ   120.00    2017-07-01 23:58:00.000 2017-07-01 23:59:00.000
399126819   A648/12FKO-2    DEZ    60.00    2017-07-01 23:58:00.000 2017-07-01 23:59:00.000
399126818   A648/12FKO-1    DEZ   180.00    2017-07-01 23:58:00.000 2017-07-01 23:59:00.000
399126816   A648/13FKO-65   DEZ     2017-07-01 23:58:00.000 2017-07-01 23:59:00.000
398331142   A661/31OFN-1    DEZ   120.00    2017-07-01 23:58:00.000 2017-07-01 23:59:00.000
398331143   A661/31OFN-2    DEZ     2017-07-01 23:58:00.000 2017-07-01 23:59:00.000
483492739   A5/28FKN-65 DEZ     2017-07-01 23:58:00.000 2017-07-01 23:59:00.000
483492735   A661/23FRS-97   DEZ    60.00    2017-07-01 23:58:00.000 2017-07-01 23:59:00.000

是否有任何其他方法或解决方法可以在 R 中的 spark-cluster 上解决此任务? 我会很高兴得到您的帮助!

【问题讨论】:

    标签: r apache-spark timestamp time-series sparklyr


    【解决方案1】:

    找到一个最小值和最大值作为纪元时间:

    df <- copy_to(sc, tibble(id=1:4, timestamp=c(
        "2017-07-01 23:49:00.000", "2017-07-01 23:50:00.000",
        # 6 minutes gap
        "2017-07-01 23:56:00.000",
        # 1 minute gap
        "2017-07-01 23:58:00.000")
    ), "df", overwrite=TRUE)
    
    min_max <- df %>% 
      summarise(min(unix_timestamp(timestamp)), max(unix_timestamp(timestamp))) %>% 
      collect() %>% 
      unlist()
    

    生成从min(epoch_time)max(epoch_time) + interval 的参考范围:

    library(glue) 
    
    query <- glue("SELECT id AS timestamp FROM RANGE({min_max[1]}, {min_max[2] + 60}, 60)") %>%
      as.character()
    
    ref <- spark_session(sc) %>% invoke("sql", query) %>% 
      sdf_register() %>%
      mutate(timestamp = from_unixtime(timestamp, "yyyy-MM-dd HH:mm:ss.SSS"))
    

    外部连接两者:

    ref %>% left_join(df, by="timestamp")
    
    # Source:   lazy query [?? x 2]
    # Database: spark_connection
       timesptamp                 id
       <chr>                   <int>
     1 2017-07-01 23:49:00.000     1
     2 2017-07-01 23:50:00.000     2
     3 2017-07-01 23:51:00.000    NA
     4 2017-07-01 23:52:00.000    NA
     5 2017-07-01 23:53:00.000    NA
     6 2017-07-01 23:54:00.000    NA
     7 2017-07-01 23:55:00.000    NA
     8 2017-07-01 23:56:00.000     3
     9 2017-07-01 23:57:00.000    NA
    10 2017-07-01 23:58:00.000     4
    # ... with more rows
    

    注意

    如果您遇到与SPARK-20145 相关的问题,您可以将 SQL 查询替换为:

    spark_session(sc) %>%
      invoke("range", as.integer(min_max[1]), as.integer(min_max[2]), 60L) %>% 
      sdf_register()
    

    【讨论】:

    • 在这个例子中如何使用invoke()功能+ tbl(sc, df)?我已经用 tbl_cache() 缓存了数据。我的数据位于 Hadoop-Cluster/Hive 外部表中。在定义 ref-df 之前,它工作得很好。谢谢!
    • 同理。如何加载数据并不重要。 invoke 部分并没有真正使用输入数据。
    • 是否可以检查缺少的时间戳是指哪个elemuid?比如:在elemuid“399126817”,时间戳“2017-9-19 23:50:00”缺失。也许在invoke 之前有一些group_by() 命令?
    猜你喜欢
    • 1970-01-01
    • 2020-12-09
    • 1970-01-01
    • 2018-07-21
    • 1970-01-01
    • 1970-01-01
    • 2017-09-13
    • 2019-09-22
    • 2021-11-17
    相关资源
    最近更新 更多