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