簡體   English   中英

每組填充時間序列的有效方法

[英]Efficient way to Fill Time-Series per group

我正在尋找一種按時間填充每個組的時間序列數據集的方法。 我使用的效率非常低下的方法是按組split數據集,並在該列表的所有元素中應用自定義時間序列填充函數(在最大和最小之間創建序列,然后合並)。 不用說,此操作不會通過拆分。

我的數據集看起來像

  source grp cnt 1: 83 2017-06-06 13:00:00 1 2: 83 2017-06-06 23:00:00 1 3: 83 2017-06-07 03:00:00 1 4: 83 2017-06-07 07:00:00 2 5: 83 2017-06-07 13:00:00 1 6: 83 2017-06-07 19:00:00 1 7: 83 2017-06-08 00:00:00 1 8: 83 2017-06-08 14:00:00 1 9: 83 2017-06-08 15:00:00 1 10: 83 2017-06-08 20:00:00 1 11: 137 2017-06-04 02:00:00 1 12: 137 2017-06-04 05:00:00 1 13: 137 2017-06-04 23:00:00 1 ... 

我的嘗試是通過利用complete函數來使用tidyverse方法,即

library(tidyverse)

d1 %>% 
 group_by(source) %>% 
 complete(source, grp = seq(min(grp), max(grp), by = 'hour'))

但是,在大約40-45秒后,出現了一個進度條(顯然是某些dydyverse功能的一種簡潔功能-我懷疑在這種情況下complete ),估計需要9個小時才能完成。 我的數據集非常大,這不是最簡單的操作,因此我一直在尋找真正有效的方法。

數據

#dput(d1)
structure(list(source = c("83", "83", "83", "83", "83", "83", 
"83", "83", "83", "83", "137", "137", "137", "137", "137", "137", 
"137", "137", "137", "137", "137", "137", "137", "137"), grp = structure(c(1496743200, 
1496779200, 1496793600, 1496808000, 1496829600, 1496851200, 1496869200, 
1496919600, 1496923200, 1496941200, 1496530800, 1496541600, 1496606400, 
1496617200, 1496649600, 1496696400, 1496808000, 1496844000, 1496876400, 
1496962800, 1497880800, 1497888000, 1497978000, 1497996000), class = c("POSIXct", 
"POSIXt"), tzone = ""), cnt = c(1L, 1L, 1L, 2L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L
)), .Names = c("source", "grp", "cnt"), row.names = c(NA, -24L
), class = "data.frame")

看來data.table實際上比tidyverse選項要快得多。 因此,只需將以上內容轉換為data.table (@Frank的補全),就可以在不到3分鍾的時間內完成操作。

library(data.table)

mDT = setDT(d1)[, .(grp = seq(min(grp), max(grp), by = "hour")), by = source]
new_D <- d1[mDT, on = names(mDT)]

new_D <- new_D[, cnt := replace(cnt, is.na(cnt), 0)] #If needed

這也可以使用動物園來完成。 這比問題中的代碼和數據快一個數量級,但沒有data.table解決方案快,盡管如果不需要下面顯示的最后一行代碼,則有可能進一步提高它的速度。

我們將d1讀入一個動物園對象z將其分割成一個多元時間序列,每個源都有一個列。 然后,我們將其與所有時間的零寬度序列合並,並使用melt=TRUE參數將其強化為數據框,以獲取長格式data.frame。 如果可以使用一個寬泛的多元動物園系列,那么您可以跳過最后一行,這樣可以更快。

library(zoo)

z <- read.zoo(d1, split = 1, index = 2) # wide form
zz <- merge(z, zoo(, seq(start(z), end(z), "hour"))) # expand
fortify(zz, melt = TRUE) # convert to long form data.frame

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM