【问题标题】:Inner join on large dataset best practices大型数据集最佳实践的内部联接
【发布时间】:2020-02-09 11:46:51
【问题描述】:

我正在尝试使用dplyr::inner_join 合并两个大型数据集(每个大约 350 万行)。 我正在开发一台具有 40 多个内核的强大机器。我不确定我是否正在利用机器本身,因为无论如何我都没有并行化任务。 我应该如何解决这个需要大量运行的问题?

最好的

【问题讨论】:

  • 我遇到了同样的问题recently,你真的必须使用data.table。有一些关于合并大型数据集的一般提示 herehere

标签: r parallel-processing dplyr bigdata


【解决方案1】:

我认为 3.5M 内部连接不会有性能问题,除非由于数据集中键列的重复(连接列的重复值),连接后您的两个最终数据集将是 3.5M * 3.5M

通常在 R 中,没有使用多核的函数。为此,您必须将可以单独处理的数据分批划分,然后将最终结果组合在一起并进一步计算。这是使用库dplyr & doParallel的伪代码

library(dplyr)
library(doParallel)

# Parallel configuration #####
cpuCount <- 10
# Note that doParallel will replicated your environment to and process on multiple core
# so if your environment is 10GB memory & you use 10 core
# it would required 10GBx10=100GB RAM to process data parallel
registerDoParallel(cpuCount)

data_1 # 3.5M rows records with key column is id_1 & value column value_1
data_2 # 3.5M rows records with key columns are id_1 & id_2

# Goal is to calculate some stats/summary of value_1 for each combination of id_1 + id_2
id_1_unique <- unique(data_1$id_1)
batchStep <- 1000
batch_id_1 <- seq(1, length(id_1_unique )+batchStep , by=batchStep )

# Do the join for each batch id_1 & summary/calculation then return the final_data
# foreach will result a list, for this psuedo code it is a list of datasets
# which can be combined use bind_rows
summaryData <- bind_rows(foreach(index=1:(length(batch_id_1)-1)) %dopar% {
    batch_id_1_current <- id_1_unique[index:index+batchStep-1]
    batch_data_1 <- data_1 %>% filter(id_1 %in% batch_id_1_current)
    joined_data <- inner_join(batch_data_1, data_2, by="id_1")
    final_data <- joined_data %>%
        group_by(id_1, id_2) %>%
        #calculation code here
        summary(calculated_value_1=sum(value_1)) %>%
        ungroup()
    return(final_data)
})

【讨论】:

  • 嗨@Sinh,你是怎么到达batch_data_2的?你可以编辑你的代码来显示吗?谢谢。
  • 对不起 - 没有 batch_data_2 只是 inner_joindata_2 自动限制为仅匹配 batch_data_1 的行。如果两个数据集太大而无法同时加载,则取决于您的内存限制 - 您可能希望将它们分开,保存在磁盘上并分别处理每个批处理文件。
【解决方案2】:

您应该尝试使用 data.table 包,对于大型数据集,它比 dplyr 大得多 more efficient。我从here.复制了内部连接代码

library(data.table)
DT <- data.table(x=rep(c("b","a","c"),each=3), y=c(1,3,6), v=1:9)
X  <- data.table(x=c("c","b"), v=8:7, foo=c(4,2))
DT[X, on="x", nomatch=0] # inner join
                         # SELECT DT INNER JOIN X ON DT$x = X$x

虽然data.table 不使用并行化,但它会比inner_join 更快,并且据我所知是最佳选择。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-03-07
    • 2013-12-06
    • 1970-01-01
    • 2019-03-15
    • 2016-09-19
    • 2015-10-29
    • 1970-01-01
    • 2016-04-04
    相关资源
    最近更新 更多