例如我有两个文件:
文件1:
id chrom start end strand
g1 11 98566330 98566433 -
g2 11 98566295 98566433 -
g3 11 98566581 98566836 -
file2的
id chrom start end strand gene_id gene_name somecol1...somecol10
g1 11 98566330 98566433 - ENSMUSG00000017210 Med24
g2 11 98566295 98566433 - ENSMUSG00000017210 Med24
g3 11 98566581 98566836 - ENSMUSG00000017210 Med24
期望的输出
id chrom start end strand gene_id gene_namesomecol1...somecol10
g1 11 98566330 98566433 - ENSMUSG00000017210 Med24
g2 11 98566295 98566433 - ENSMUSG00000017210 Med24
g3 11 98566581 98566836 - ENSMUSG00000017210 Med24
我基本上想要做的是从两个文件中获取匹配id列,如果匹配,则在新文件中打印/写入file1和file2中的一些列(我当前的代码)
with open('~/outfile.txt', 'w') as w:
for id1 in c1: #c1 is list where i append each line from file1
for id2 in d1: #d2 is list where i append each line from file2
if id1[0] in id2[0]: #is this condition faster (condition1)
# if id1[0] == id2[0]:#or this condition is faster (condition2)
out = ('\t'.join(id2[0:6]),id1[1],id1[2],id2[9],id2[10])
w.write('\t'.join(out) + '\n')
问题是这个代码按条件2工作,但它很慢可能是因为我试图匹配列表c1和d1之间的每一行id1[0] == id2[0]
,也因为file2有~500000行。
目前我只能提出两个我想要学习的条件,可能会使代码更快
是否有更好的逻辑可以提高速度。
编辑:
我需要匹配文件col0(id)和file2 col(id),如果是真,那么切片col0:6中的元素,来自file1的col [1,2]和来自file2的col9,10
期望的输出
id(file2) chrom(file2) start(file2) end(file2) strand(file2) gene_id(file2) gene_name(file2)somecol1(file1)...somecol10(file1)
g1 11 98566330 98566433 - ENSMUSG00000017210 Med24
g2 11 98566295 98566433 - ENSMUSG00000017210 Med24
g3 11 98566581 98566836 - ENSMUSG00000017210 Med24
答案 0 :(得分:1)
如果我理解正确,只有当id
字段位于第一个文件中时,才希望保留第二个文件中的行。
我会一直使用csv
模块,这更清晰。
首先,我将构建一组id
字段,用于从文件1内容快速查找(每行只有5个字段)
然后我会读取第二个文件,并且仅当行id包含在集合中时才将行写入第三个文件。您将受益于set
查找的速度:
import csv
with open("file1.txt") as file1:
cr = csv.reader(file1,delimiter="\t")
next(cr) # skip title
subset = {row[0] for row in cr} # build lookup set in a set comprehension for ids
with open("file2.txt") as file2, open("result.txt","w",newline="") as file3: # python 2: open("result.txt","wb")
cr = csv.reader(file2,delimiter="\t")
cw = csv.writer(file3,delimiter="\t")
cw.writerow(next(cr)) # write title
cw.writerows(row for row in cr if row[0] in subset)
答案 1 :(得分:1)
您需要知道花费时间以了解如何最好地解决问题。猜测它将会读取和写入文件,其他一切都将达到......几乎没有。
如果您可以专注于问题领域,优化是很好的 - 这样其他所有内容都可以保持清晰可读的Python。因此,我首先要分析您的代码。 cProfile is a good place to start您的调查,可能还需要创建一些功能来划分您的工作,以便您可以看到花时间。
我最近做过edX ITMO竞争性编程课程,速度非常重要。 Python I / O是一个关键障碍,因此读取和写入都得到了优化。尽可能使用重要块进行写入,因此您可能需要在写入之前聚合数据。 Python的memory mapped reads被用来加快阅读速度。为了举例说明使用mmap的相对容易程度,顶部注释掉的代码执行下面未注释的readlines的mmap等价物:
# with mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ) as mm:
# end = mm.size()
# while mm.tell() < end:
# for l in mm.readline().split():
# print(';'.join(l.decode('ascii').split(',')))
# with open("out1", 'w') as o:
with open(filename, 'r') as f:
for l in f.readlines():
# ll.append('.'.join(l.split(',')))
# o.writelines(l[13:])
# print(l[13:], end='')
print('.'.join(l.split(',')), end='')