由于记录数而导致交易性能问题

时间:2019-06-09 13:14:48

标签: r performance

警告:事实证明,我的原始版本存在一些范围界定问题,也未达到预期的目标。


我有一个100000(一万)条记录的数据集,我想将其分成多行。每个记录都有一个字段,该字段包含一个字符串,该字符串的名称由8个项目组成,并用分号(;)分隔。最终结果是每1行原始数据就有8行。

我编写了以下函数来帮助我实现这一目标,但它似乎并不是很高效,这反过来意味着执行该过程的时间不可能太长(我已经让它运行了至少30分钟,现在仍然没有还没完成)。因此,我正在寻找各种方法来改善运行时间的提示。

一点点背景:

row[1]是用分号分隔的字符串。

row[5]是项集合的索引,该项集合必须与单独的项一起保存,以便以后可以将它们关联起来。

toSingleItems <- function(data, sep = ';') {
  returnVal <- vector("list", nrows(data) * 8)
  i <- 1

  apply(data, 1, FUN = function(row) {
    splitDeck = str_split(row[1], sep)
    lapply(splitDeck, FUN=function(item){
      returnVal[[i]] <- c(row[5], item)
      i <- i + 1
    })
  })
  return(returnVal)
}

欢迎任何提示,谢谢!!

偷偷摸摸的编辑:显而易见的解决方案当然是以任何方式减少数据集。我已经做到了这一点(达到10000),但是即使那样,性能仍然非常糟糕。

数据可能如下所示:

"a;b;c;d;w;x;y;z"
"e;f;g;h;i;j;k;l"

在这种情况下,输出将如下所示:

1, "a"
1, "b"
1, "c"
1, "d"
1, "w"
1, "x"
1, "y"
1, "z"
2, "e"
2, "f"
2, "g"
2, "h"
2, "i"
2, "j"
2, "k"
2, "l"

2 个答案:

答案 0 :(得分:1)

这是一个更简单的示例,可能代表您的数据?

df = data.frame(x = c("a;b;c;d", "e;f;g;h"), y = 1:2, stringsAsFactors=FALSE)

要拆分x,我做了

elts = strsplit(df$x, ";")

我们需要知道每个元素的长度,即lengths(elts)。 然后我把东西放回去

data.frame(x = unlist(elts), y = rep(y, lengths(elts))

也许一个概括就是按照上面的方法进行分割和计算长度,复制整个数据集

idx = rep(seq_len(nrow(df)), lengths(elts))
df = df[idx,]

并更新相关列

df$x = unlist(elts)

tidyr软件包提供了非常方便的功能

df %>% tidyr::separate_rows(x, sep = ";")

答案 1 :(得分:1)

看看下面的代码是否有帮助。

library(tidyverse)
df = data.frame(id= c(1,2), value=c("a;b;c;d;w;x;y;z", "e;f;g;h;i;j;k;l"))

df = df %>% 
  mutate(value = str_split(value,pattern=";", n=8)) %>% # transform the string to list
  unnest # list to individual rows