【问题标题】:How to create dummies using a long data frame?如何使用长数据框创建假人?
【发布时间】:2020-07-18 16:24:12
【问题描述】:

我有一个 2 列 1316171 行的数据框,但一个 2 列 7621 行的数据框也会产生问题。

myFun <- function(n = 5000) {
  a <- do.call(paste0, replicate(5, sample(LETTERS, n, TRUE), FALSE))
  paste0(a, sprintf("%04d", sample(9999, n, TRUE)), sample(LETTERS, n, TRUE))
}

m <- myFun(7021)
d <- myFun(7021)

df <-data.frame(m,d)

我想创建虚拟变量,所以我使用以下非常简单的代码:

genes2 <- fastDummies::dummy_cols(df, select_columns = "m") 

但是,我不断收到此错误消息:

 Warning message:
    In data.table::alloc.col(.data, ncol(.data) + length(unique_vals)) :
      tl (64004) is greater than 10,000 items over-allocated (l = 15170). If you didn't set the datatable.alloccol option to be very large, please report to data.table issue tracker including the result of sessionInfo()

我了解到,当您创建一个太大而无法处理的数据表时会发生这种情况,我在 StackOverflow 上发现

默认在 v1.8.8 中:

options()$datatable.alloccol 最大值(100, 2 * ncol(DT)) 而且它可能不是最好的默认值,您应该尝试将其更改为:

options(datatable.alloccol = quote(max(100L, ncol(DT)+64L))

但即使在尝试之后,我也会收到相同的错误消息。

我还了解到,您可以使用 alloc.col 函数将 data.table 中所需的列数量预先分配给一个大于预期 ncol 的数字。

例如:

alloc.col(myDataTable, 7021)

但不幸的是,这对我来说不起作用,可能是因为我在 fastDummies 代码之前或之后使用它。

如何创建虚拟变量并以函数方式分配列数?

【问题讨论】:

    标签: r dataframe datatable


    【解决方案1】:

    一个不完整的答案,但渴望评论。 tl;dr 你的完整问题会出现大内存问题,可以通过使用稀疏矩阵来缓解。

    • 这是一个警告,而不是错误:值得尝试理解和解决它,但它实际上不应该妨碍执行任何操作...?
    • 我没有收到此警告(我使用的是 data.table 版本 1.12.8)。更新您的版本有帮助吗?
    • 我看不出您发布的代码实际上将如何涉及data.table(尽管如果您以df &lt;- data.table(m,d) 开头而不是使用data.frame() 会这样)?

    但是,如果您打算将其扩展到 1316171 行,您可能会遇到更大的问题。您给出的示例创建了一个 190 Mb 的对象:

    format(object.size(genes2),"Mb") ## 190.4 Mb
    

    我们可以通过计算7021 (number of rows) * 7021 (number of columns; see below) * 4 (bytes per integer) / 2^20 (bytes per Mb)得到这个数字

    n <- 7021
    n*n*4/2^20 ## 188.80434
    

    实际对象要大一些,因为(1)fast_dummies 还保留了md 两列字符向量; (2) 有一点开销。

    在您的示例中,每一行都是唯一的(因为您从中生成“基因名称”的样本空间很大),因此我们最终会得到与行一样多的假人(列)。如果您的完整数据集是这样(即您有 1316171 个唯一基因名称),您最终会得到一个占用超过 6 TB 空间的对象。 p>

    n <- 1316171
    n*n*4/2^40   ## 6.3
    

    这可能是可管理的,但可能无法使用本地硬件资源。

    也许您只有 10,000 个不同的基因名称?在这种情况下,您需要:

    m <- 1e4
    m*n*4/2^30  ## 49 Gigabytes
    

    处理一个 49 Gb 的对象是合理的,但仍然超出了大多数标准硬件的范围(如果你真的想对这个对象做任何事情,而不仅仅是将它存储在内存中,你将需要这个内存大小的几倍)。

    (我使用的是稍微老式的约定,即 1 Kb=2^10 字节、1 Mb=2^20、1 Gb = 2^30、1 Tb = 2^40)。

    如果您打算在下游使用的机器将支持稀疏矩阵,那么我强烈建议您将虚拟矩阵构造为稀疏矩阵,例如:

    f2 <- Matrix:::fac2sparse(myFun(7021))
    dim(f2)  ## 7021 7021
    object.size(f2) ## 619400 bytes
    

    这是 620 千字节,而不是之前的 188 Mb。

    您的全尺寸问题的虚拟矩阵需要

    system.time(f3 <- Matrix:::fac2sparse(myFun(1316171)))
    format(object.size(f3),"Mb")
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-08-16
      • 2021-11-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-19
      • 1970-01-01
      • 2021-12-19
      相关资源
      最近更新 更多