首页 > 解决方案 > 由于记录数量而转换为事务性能问题

问题描述

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


我有一个包含 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"

标签: rperformance

解决方案


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

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 = ";")

推荐阅读