7

我有大约 50 个 CSV 文件,每个文件有 60,000 行,列数不等。我想按列合并所有 CSV 文件。我尝试在 MATLAB 中执行此操作,方法是转置每个 csv 文件并重新保存到磁盘,然后使用命令行连接它们。这花了我一个多星期的时间,最终结果需要再次转置!我必须再做一次,我正在寻找一个不会再花一周时间的解决方案。任何帮助,将不胜感激。

4

5 回答 5

10

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

听起来像转置猫转置。使用粘贴水平连接文件。

paste -d ',' a.csv b.csv c.csv ... > result.csv
于 2013-08-09T06:44:13.757 回答
2

可以设置Pythoncsv模块,以便每条记录都是以列名作为键的字典。您应该能够以这种方式读取所有文件作为字典,并将它们写入包含所有列的输出文件。

Python 易于使用,因此对于任何语言的程序员来说这应该是相当简单的。

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

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

于 2013-08-09T05:33:48.047 回答
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='')
于 2013-08-09T15:49:29.753 回答
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对象存储在向量/数组/列表中。在这种情况下,您只需从每个文件中一次读取一行并将其写入输出。

于 2013-08-09T05:58:02.233 回答
1

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

假设文件“a.csv”具有字段“a1、a2、a3、a4、a5”。

并假设文件“b.csv”具有字段“b1、b2、b3”。

我们想加入 a1 = b2 的行。并且输出格式应该是“a1, a4, b3”。

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

}
于 2016-10-22T17:50:58.873 回答