Замена NA на LOCF с использованием Sparklyr - PullRequest
0 голосов
/ 03 июля 2019

Моя цель - заменить NA во фрейме данных искры, используя метод Последнее наблюдение перенесено . Я написал следующий код и работает . Тем не менее, для большого набора данных это занимает больше времени, чем ожидалось.

Было бы замечательно, если бы кто-то мог порекомендовать лучший подход или улучшить код.

Пример и код со Sparklyr

В следующем примере NA заменяются после их заказа с использованием time и сгруппировать их по grp.

df_with_nas <- data.frame(time = seq(as.Date('2001/01/01'), 
                                as.Date('2010/01/01'), length.out = 10),
                          grp = c(rep(1, 5), rep(2, 5)),
                          v1 = c(1, rep(NA, 3), 5, rep(NA, 5)),
                          v2 = c(NA, NA, 3, rep(NA, 4), 3, NA, NA))

tbl <- copy_to(sc, df_with_nas, overwrite = TRUE)

tbl %>%
  spark_apply(function(df) {
    library(dplyr)
    na_locf <- function(x) {
      v <- !is.na(x)
      c(NA, x[v])[cumsum(v) + 1]
    }
    df %>% arrange(time) %>% group_by(grp) %>% mutate_at(vars(-v1, -grp), 
    funs(na_locf(.)))
  })

# # Source: spark<?> [?? x 4]
#      time   grp    v1    v2
#     <dbl> <dbl> <dbl> <dbl>
#  1 11323      1     1   NaN
#  2 11688.     1   NaN   NaN
#  3 12053.     1   NaN     3
#  4 12419.     1   NaN     3
#  5 12784.     1     5     3
#  6 13149.     2   NaN   NaN
#  7 13514.     2   NaN   NaN
#  8 13880.     2   NaN     3
#  9 14245.     2   NaN     3
# 10 14610      2   NaN     3

data.table

Для данных, которые у меня есть на данный момент, следующий подход с data.table работает довольно быстро. Я ожидаю, что размер данных скоро увеличится, и тогда мне, возможно, придется положиться на sparklyr.

library(data.table)
setDT(df_with_nas)
df_with_nas <- df_with_nas[order(time)]
cols <- c("v1", "v2")

df_with_nas[, (cols) := zoo::na.locf(.SD, na.rm = FALSE), 
                                 by = grp, .SDcols = cols]
...