在大型TSV文件中进行删除/重排/添加操作 Python

2 投票
3 回答
1130 浏览
提问于 2025-04-18 10:17

我有一个非常大的tsv文件(1.2GB,5列,3800万行)。我想删除一列,添加一列ID(从1到3800万),并重新排列列的顺序。请问我该如何在不占用过多内存的情况下做到这一点?

我选择的编程语言是Python,不过也可以考虑其他解决方案。

3 个回答

1

这个问题的答案很大程度上取决于你需要多少上下文信息来重写这些行,以及确定新的顺序。

如果可以在不考虑上下文的情况下重写每一行(这取决于ID号码是怎么来的),那么你可以使用 csv 模块逐行读取文件,就像 @Tal Kremerman 所示的那样,然后按原来的顺序逐行写出。如果你此时能确定行的正确顺序,那么你可以添加一个额外的字段,指明它们应该出现的新顺序。

然后你可以进行第二次处理,把行排序或重新排列成正确的顺序。最近有很多关于“如何用Python排序大文件”的讨论,比如 如何用Python排序大文件? 我认为Tal Kremerman说得对,提问者只是想重新排列列,而不是行

1

你可以用 awk 来实现这个功能,不过我得提醒你,1.2GB的数据会占用很多内存。

如果你想删除 c3 列的话,

awk -F"\t" 'BEGIN{OFS="\t"}{print $1,$2,$4,$5,NR}' input.txt > output.txt

原始输出是 c1 c2 c4 c5 columnId(从1到38m)

$1 代表第一列,$2 代表第二列,依此类推。NR 是行号。

如果你想重新排列列的顺序,只需要改变 $1、$2、$4、$5 和 NR 的顺序就可以了。

2

你可以一次读取、处理和写入一行数据。这样做不需要把整个文件都加载到内存中,所以会占用很少的内存。

import csv
with open(fileinpath, 'rb') as fin, open(fileoutpath, 'wb') as fout:
    freader = csv.reader(fin, delimiter = '\t')
    fwriter = csv.writer(fout, delimiter = '\t')
    idx = 1
    for line in freader:
        line[4], line[0] = line[0], line[4] #switches position between first and last column
        del line[3] #delete fourth column
        line.insert(0, idx)
        fwriter.writerow(line)
        idx += 1

(这个例子是用python2.7写的,演示了如何删除第四列)

关于调整顺序——我想你指的是列的顺序——这可以在处理数据的部分来完成。这里有一个例子,展示了如何交换第一列和最后一列的位置。

撰写回答