最佳排序行/列以减小r data.frame对象的大小



是否有一个好方法或算法来确定行的最佳排序和排列行,以最大程度地减少磁盘上的r data.frame的文件大小?

考虑以下数据:

# Init
library(dplyr)
set.seed(12345)
n_rows <- 10e6
df_1 <- data.frame(
    V1 = sample(1:10, n_rows, replace=TRUE),
    V2 = sample(1:2, n_rows, replace=TRUE),
    V3 = sample(1:100, n_rows, replace=TRUE),
    V4 = sample(1:1000, n_rows, replace=TRUE),
    V5 = sample(1:5, n_rows, replace=TRUE)
) %>% as_data_frame()
df_2 <- df_1 %>% arrange(
    V2,    V5,    V1,    V3,    V4
)
df_3 <- df_2 %>% select(
    V2,    V5,    V1,    V3,    V4
)
saveRDS(df_1, "temp_1.RDS")
saveRDS(df_2, "temp_2.RDS")
saveRDS(df_3, "temp_3.RDS")

输出文件尺寸为:

  • df_1/temp_1.rds = 43,770 kb
  • df_2/temp_2.rds = 10,091 kb
  • df_3/temp_3.rds = 10,089 kb

在这种情况下,我们通过以合理的方式订购行来观察文件大小的大幅减少,并通过排列行后以"某种方式"列来减少列。

是否有一种自动方法来制定最佳的列顺序以及排列它们的最佳顺序?该方法可能使用动态编程或其他内容,但是我希望那里有一个可以使用实现的R软件包。

一旦加载在内存中,预先安排的对象通常会更具性能吗?我猜是做与预先排序的分组一致的事情的"是"。

编辑,出于兴趣,这是一些简单任务的时机结果:

# Do a process on a data.frame
process_func <- function(x){
    x %>% group_by(
        V2,V5,V1
    ) %>% summarise(
        sum(V4),
        sum(V3)
    )
}
system.time(replicate(100, process_func(df_1)))
system.time(replicate(100, process_func(df_2)))
system.time(replicate(100, process_func(df_3)))

相同的任务需要(重复100次(:

  • DF_1上的95秒
  • DF_2上的47秒
  • DF_3上的48秒

作为一种良好的启发式,我将首先按列的列订购。更最佳的解决方案将需要更多的计算时间,考虑到问题的大小,这将很难。

您可以做:

df_4 <- df_1 %>% 
  arrange_at(., names(sort(sapply(., n_distinct))))

最新更新