在 data.table 中拆分字符串并转换为长格式的快速方法
Posted
技术标签:
【中文标题】在 data.table 中拆分字符串并转换为长格式的快速方法【英文标题】:Fast way to split string and convert to long format in data.table 【发布时间】:2014-05-05 20:54:03 【问题描述】:我做以下事情
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
不是正确的做法?
【问题讨论】:
请发布最小样本数据 您当前的“string_column”变量中有重复的值。应该是这样吗? 不,抱歉,需要唯一的行(去掉 replace = TRUE ) 【参考方案1】:如果您放弃使用“stringr”中的str_split()
而只使用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
这是否会使您的处理时间从 1 小时缩短到 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”列并执行相同操作,您将获得相同的结果。
【讨论】:
谢谢,在我的情况下,我的速度提高了十倍 - 是 - 3660s,现在 - 370s以上是关于在 data.table 中拆分字符串并转换为长格式的快速方法的主要内容,如果未能解决你的问题,请参考以下文章
R语言将dataframe宽表转化为长表实战:使用data.table使用tidyr包gather函数使用reshape2包