代码之家  ›  专栏  ›  技术社区  ›  Chris Beeley

在内存中使用奇怪的粘贴

  •  4
  • Chris Beeley  · 技术社区  · 6 年前

    所以我的实际数据集是1600万行,是保密的,但我可以很容易地说明发生了什么。我一点也不理解这种行为,它与我读过的所有东西都背道而驰,或者至少我认为它确实如此。

    这是一个带有字符串和日期的数据框(真正的数据框有更多的列和行)

    library(tidyverse)
    
    test = data.frame("a" = letters, 
                      "b" = seq.Date(as.Date("2018-01-01"), 
                                     as.Date("2018-01-26"), "days")
    )
    

    我想制作第三列,将前两列粘贴在一起。我是这样做的:

    finalTest = test %>%
      mutate(c = paste(a, b))
    

    如果我这样做的话,有1600万行,它会从使用的2GB内存增加到近8GB,进程会被服务器(有8GB内存)杀死。

    但是,如果我将数据集一分为二,粘贴列,然后rbind,就可以了,尽管这样做是在创建不必要的对象(整个数据集只有大约700MB,因此对象适合RAM是有意义的)。

    test1 = test %>%
      filter(row_number() <= floor(n()/2)) %>%
      mutate(c = paste(a, b))
    
    test2 = test %>%
      filter(row_number() > floor(n()/2)) %>%
      mutate(c = paste(a, b))
    
    finalTest2 = rbind(test1, test2)
    

    这很好。这些对象似乎适合存储在内存中,但在对它们进行操作时却不适合。但到底发生了什么,记忆如此密集?

    我完全不明白。这是预期的行为吗?它是唯一可以粘贴的吗?用字符串和日期粘贴?还有别的吗?

    0 回复  |  直到 6 年前
        1
  •  1
  •   francois artin    3 年前

    我也经历过。。。如果您的数据帧中开始有16M行,我建议您真的不要麻烦使用dplyr优化内存使用,只需使用数据即可。桌子速度快得多,内存效率高,虽然语法复杂,但有一些变通方法(见下文)。 确保你理解这些数据。表内存管理通常是通过引用进行的,不像dplyr进行复制(这就是性能差异的原因)。
    因为语法对于数据来说是非常困难的。一开始可能有点困难,可以使用dtplyr包将dplyr代码转换为数据。表格(使用show_查询功能)或查看此网页: https://atrebas.github.io/post/2019-03-03-datatable-dplyr/ 我发现它对熟悉dplyr但不熟悉数据的人非常有用。桌子

    如果你真的想坚持使用dplyr,请确保数据。有时,在使用此框架之前,请忘记在某个地方使用的行为。