读取和解析TSV文件,然后将其操作以保存为CSV(*高效*)

CJH*_*CJH 64 python csv file tab-delimited-text

我的源数据是TSV文件,6列,超过200万行.

这就是我想要完成的事情:

  1. 我需要读取此源文件中3列(3,4,5)中的数据
  2. 第五列是整数.我需要使用此整数值来复制行条目,使用第三列和第四列中的数据(按整数次数).
  3. 我想将#2的输出写入CSV格式的输出文件.

以下是我提出的建议.

我的问题:这是一种有效的方法吗?当尝试200万行时,似乎可能是密集的.

首先,我制作了一个样本选项卡单独的文件,并将其命名为"sample.txt".它是基本的,只有四行:

Row1_Column1    Row1-Column2    Row1-Column3    Row1-Column4    2   Row1-Column6
Row2_Column1    Row2-Column2    Row2-Column3    Row2-Column4    3   Row2-Column6
Row3_Column1    Row3-Column2    Row3-Column3    Row3-Column4    1   Row3-Column6
Row4_Column1    Row4-Column2    Row4-Column3    Row4-Column4    2   Row4-Column6
Run Code Online (Sandbox Code Playgroud)

然后我有这个代码:

import csv 

with open('sample.txt','r') as tsv:
    AoA = [line.strip().split('\t') for line in tsv]

for a in AoA:
    count = int(a[4])
    while count > 0:
        with open('sample_new.csv', 'a', newline='') as csvfile:
            csvwriter = csv.writer(csvfile, delimiter=',')
            csvwriter.writerow([a[2], a[3]])
        count = count - 1
Run Code Online (Sandbox Code Playgroud)

Mar*_*ers 129

您应该使用该csv模块读取制表符分隔值文件.不要读入内存中一气呵成.您阅读的每一行都包含将行写入输出CSV文件所需的所有信息.始终保持输出文件打开.

import csv

with open('sample.txt', newline='') as tsvin, open('new.csv', 'w', newline='') as csvout:
    tsvin = csv.reader(tsvin, delimiter='\t')
    csvout = csv.writer(csvout)

    for row in tsvin:
        count = int(row[4])
        if count > 0:
            csvout.writerows([row[2:4] for _ in range(count)])
Run Code Online (Sandbox Code Playgroud)

或者,使用itertools模块重复itertools.repeat():

from itertools import repeat
import csv

with open('sample.txt', newline='') as tsvin, open('new.csv', 'w', newline='') as csvout:
    tsvin = csv.reader(tsvin, delimiter='\t')
    csvout = csv.writer(csvout)

    for row in tsvin:
        count = int(row[4])
        if count > 0:
            csvout.writerows(repeat(row[2:4], count))
Run Code Online (Sandbox Code Playgroud)

  • @SamuelLampa:它只是一个占位符; 它是一个普通的变量,比如`i`或`counter`,但在这种情况下只是意味着*我不关心这个循环变量的值是什么,因为我无论如何都忽略它*. (3认同)
  • @SamuelLampa:换句话说,按照惯例,它可以在任何需要具有分配目标但无需忽略分配值的地方使用.你也可以在元组解包中看到它:`name,_,_,score = line.split()`,例如,忽略分割线的两个中间值. (3认同)