Быстрый способ разбить строку и преобразовать в длинный формат в data.table
Я делаю следующее
library(data.table)
library(stringr)
dt <- data.table(string_column = paste(sample(c(letters, " "), 500000, replace = TRUE)
, sample(c(letters, " "), 500000, replace = TRUE)
, sample(1:500000)
, sep = " "), key = "string_column")
split_res <- dt[, list(name = unlist(str_split(string_column, '\\s+'))), by = string_column]
Для реальных данных требуется ок. 1 час на обработку dt
(10M строк) и создать split_res
(18M рядов) Из любопытства - есть ли способ ускорить процесс? Может быть unlist + str_split
это не правильный способ сделать это?
1 ответ
Вы получите большое ускорение, если просто бросите str_split()
от "stringr" и просто использовать strsplit()
,
fun1 <- function() dt[, list(name = unlist(str_split(string_column, '\\s+'))), by = string_column]
fun2 <- function() dt[, list(name = unlist(strsplit(string_column, '\\s+'))), by = string_column]
system.time(fun1())
# user system elapsed
# 172.41 0.05 172.82
system.time(fun2())
# user system elapsed
# 11.22 0.01 11.23
Я не уверен, сократит ли это ваше время обработки с одного часа до 4 минут или нет. Но, по крайней мере, вам не нужно будет вставлять эти противные подчеркивания в имена функций:-)
Если вы можете разбить на фиксированный шаблон поиска, вы можете использовать fixed = TRUE
аргумент, который даст вам еще один существенный прирост скорости.
Еще одна вещь, которую нужно учитывать, это сделать процесс вручную:
x <- strsplit(dt$string_column, "\\s+")
DT <- dt[rep(sequence(nrow(dt)), vapply(x, length, 1L))]
DT[, name := unlist(x, use.names = FALSE)]
DT
С вашими примерами данных:
fun4 <- function() {
x <- strsplit(dt$string_column, "\\s+")
DT <- dt[rep(sequence(nrow(dt)), vapply(x, length, 1L))]
DT[, name := unlist(x, use.names = FALSE)]
DT
}
# user system elapsed
# 1.79 0.01 1.82
Тем не менее, ответ не совпадает с тем, что я получаю с fun2()
, но это потому, что у вас есть дублированные значения в "string_column". Если вы добавите столбец "id" и сделаете то же самое, вы получите те же результаты.