在计算机群集上读取和合并大表

时间:2018-10-30 09:25:11

标签: merge parallel-processing cluster-computing lapply

我需要将不同的大表(每个最大10Gb)合并到一个表中。为此,我正在使用在Linux上运行的具有50多个核心和10 + Gb Ram的计算机集群。

我总是以错误消息结尾,例如:“无法分配大小为X Mb的向量”。 鉴于memory.limit(size=X)之类的命令是Windows特定的,并且不被接受,因此我找不到周围合并大型表的方法。

欢迎任何建议!

这是我使用的代码:

library(parallel)

no_cores <- detectCores() - 1
cl <- makeCluster(no_cores)

temp = list.files(pattern="*.txt$")
gc()

出现错误:

myfiles = parLapply(cl,temp, function(x) read.csv(x,
                                        header=TRUE, 
                                        sep=";",
                                        stringsAsFactors=F,
                                        encoding = "UTF-8",
                                        na.strings = c("NA","99","")))



myfiles.final = do.call(rbind, myfiles)

2 个答案:

答案 0 :(得分:1)

一种解决方法是使用python和dask。 dask数据帧主要存储在磁盘上,而不是存储在ram中,从而使您可以处理比ram数据大的数据,并且可以帮助您进行巧妙的并行化计算。可以在此kaggle帖子中找到有关处理大数据的方法的很好的指南,这可能也对您有所帮助。我还建议您查看有关出色性能here的文档。需要明确的是,如果您的数据可以使用常规R数据帧或pandas数据帧放入RAM中,则速度会更快。

这是一个简单的解决方案,它将假定您已在表中命名列以对齐concat操作。如果您对我们需要考虑的数据还有其他特殊要求,请添加到您的问题中。

#include <string.h>

void reverse(const char *input, int length, char *output) {
    int i, j, k, v;
    for (i = k = 0, v = length;; i++) {
        if (i == length || input[i] == ' ') {
            for (j = i; j-- > k;) {
                output[--v] = input[j];
            for (; i < length && input[i] == ' '; i++) {
                output[--v] = ' ';
            }
            if (v == 0) {
                output[length] = '\0';
                break;
            }
            k = i;
        }
    }
}

如果您只想将所有表放在一起,则可以使用直接python进行类似的操作。 (您也可以使用linux cat / paste)。

import dask.dataframe as dd
import glob

tmp = glob.glob("*.txt")

dfs= []
for f in tmp:
    # read the large tables
    ddf = dd.read_table(f)
    # make a list of all the dfs
    dfs.append(ddf)

#row-wise concat of the data
dd_all = dd.concat(dfs)
#repartition the df to 1 partition for saving
dd_all = dd_all.repartition(npartitions=1)

# save the data 
# provide list of one name if you don't want the partition number appended on
dd_all.to_csv(['all_big_files.tsv'], sep = '\t')

答案 1 :(得分:0)

您可以仅使用合并,例如:

    0   1   2   3
0   123 345 456 789
1   987 876 765 543

`