按列合并多个csv文件的最快方法是什么?

时间:2013-08-09 05:28:49

标签: python csv merge

我有大约50个CSV文件,每个文件有60,000行,并且列数不同。我想按列合并所有CSV文件。我已经尝试在MATLAB中通过转置每个csv文件并重新保存到磁盘,然后使用命令行来连接它们。这使我的计算机超过一周,最终结果需要再次转换!我必须再次这样做,我正在寻找一个不会再需要一周的解决方案。任何帮助将不胜感激。

5 个答案:

答案 0 :(得分:7)

  

[...]转置每个csv文件并重新保存到磁盘,然后使用命令行连接它们[...]

听起来像Transpose-Cat-Transpose。使用paste水平加入文件。

paste -d ',' a.csv b.csv c.csv ... > result.csv

答案 1 :(得分:1)

可以设置Python csv模块,以便每个记录都是一个以列名作为键的字典。您应该以这种方式将所有文件作为字典读入,并将它们写入包含所有列的外部文件。

Python易于使用,因此对于任何语言的程序员来说这都应该是微不足道的。

如果你的csv文件没有列标题,那么这将是相当多的手工工作,所以它可能不是最好的解决方案。

由于这些文件相当大,所以最好不要将它们全部读入内存一次。我建议您先打开它们,只将所有列名收集到一个列表中,然后使用该列表创建输出文件。然后,您可以将每个输入文件连接到输出文件,而无需将所有文件都存储在内存中。

答案 2 :(得分:1)

水平串联确实很简单。考虑到你了解C ++,我很惊讶你使用了MATLAB。以您的方式处理大约数GB的数据应该是几秒钟而不是几天。

根据您的描述,实际上不需要CSV处理。最简单的方法是在RAM中执行此操作。

vector< vector<string> > data( num_files );

for( int i = 0; i < num_files; i++ ) {
    ifstream input( filename[i] );
    string line;
    while( getline(input, line) ) data[i].push_back(line);
}

(做明显的健全性检查,例如确保所有向量长度相同......)

现在你拥有一切,转储它:

ofstream output("concatenated.csv");

for( int row = 0; row < num_rows; row++ ) {
    for( int f = 1; f < num_files; f++ ) {
        if( f == 0 ) output << ",";
        output << data[f][row];
    }
    output << "\n";
}

如果您不想使用所有RAM,则可以一次执行一行。您应该能够立即打开所有文件,并将ifstream对象存储在向量/数组/列表中。在这种情况下,您只需从每个文件一次读取一行并将其写入输出。

答案 3 :(得分:1)

import csv
import itertools

# put files in the order you want concatentated
csv_names = [...whatever...] 

readers = [csv.reader(open(fn, 'rb')) for fn in csv_names]
writer = csv.writer(open('result.csv', 'wb'))

for row_chunks in itertools.izip(*readers):
    writer.writerow(list(itertools.chain.from_iterable(row_chunks)))

水平连接。假设所有文件具有相同的长度。具有较低的内存开销并且速度很快。

答案适用于Python 2.在Python 3中,打开csv文件略有不同:

readers = [csv.reader(open(fn, 'r'), newline='') for fn in csv_names]
writer = csv.writer(open('result.csv', 'w'), newline='')

答案 4 :(得分:0)

使用Go:https://github.com/chrislusf/gleam

假设有文件&#34; a.csv&#34;有字段&#34; a1,a2,a3,a4,a5&#34;。

并假设文件&#34; b.csv&#34;有字段&#34; b1,b2,b3&#34;。

我们希望加入a1 = b2的行。输出格式应为&#34; a1,a4,b3&#34;。

package main

import (
    "os"

    "github.com/chrislusf/gleam"
    "github.com/chrislusf/gleam/source/csv"
)

func main() {

    f := gleam.New()
    a := f.Input(csv.New("a.csv")).Select(1,4) // a1, a4
    b := f.Input(csv.New("b.csv")).Select(2,3) // b2, b3

    a.Join(b).Fprintf(os.Stdout, "%s,%s,%s\n").Run()  // a1, a4, b3

}