繁体   English   中英

python结合了每一行:使脚本更高效

[英]python combine each pair of lines: making script more efficient

我很抱歉这个问题有多基本。

目的:这是我从软件程序中得到的输出:

1   590 SC  1.000   LEU2_YEAST  100%
1   590 EC  1.000   LEU2_ECOLI  100%
2   467 SC  1.000   FADH_YEAST  100%
2   467 EC  1.000   ADH3_ECOLI  100%
3   463 SC  1.000   6PG1_YEAST  100%
3   463 SC  0.816   6PG2_YEAST
3   463 EC  1.000   6PGD_ECOLI  100%
3   463 EC  0.903   6PG9_ECOLI
4   446 SC  1.000   YME1_YEAST  59%
4   446 EC  1.000   FTSH_ECOLI  100%
5   411 SC  1.000   ADH4_YEAST  100%
5   411 EC  1.000   ADH2_ECOLI  99%
8   256 SC  1.000   ATM1_YEAST  100%
8   256 EC  1.000   HLYB_ECOLI  99%
8   256 EC  0.987   HLY2_ECOLI
9   252 SC  1.000   MDL2_YEAST  100%
9   252 SC  0.203   MDL1_YEAST
9   252 EC  1.000   MSBA_ECOLI  99%

对于那些有生物学背景的人,我只想拿出相互匹配的热门歌曲。 对于那些具有非生物学背景的人,仅在第一列中的数字仅出现两次时,我才想提取基因对。

例如,我们可以看到数字1在文件的第一列中出现了两次:

 1  590 SC  1.000   LEU2_YEAST  100%
 1  590 EC  1.000   LEU2_ECOLI  100%

但是数字3出现4次出现在文件的第一列中:

3   463 SC  1.000   6PG1_YEAST  100%
3   463 SC  0.816   6PG2_YEAST
3   463 EC  1.000   6PGD_ECOLI  100%
3   463 EC  0.903   6PG9_ECOLI

因此,对于此示例文件,输出将如下所示:

LEU2_YEAST LEU2_ECOLI
FADH_YEAST ADH3_ECOLI
YME1_YEAST FTSH_ECOLI
ADH4_YEAST ADH2_ECOLI

因为这些是文件中仅有的四对线。

这是我的代码:

import sys
Dict1 = {}
for line in open(sys.argv[1]):
    line = line.strip().split()
    if line[0] not in Dict1.keys():
        Dict1[line[0]] = [line[4]] 
    elif line[0] in Dict1.keys():
        Dict1[line[0]].append(line[4])

for i in Dict1.values():
    if len(i) == 2:
        print i[0] + "\t" + i[1] 

这有效,它输出的输出是:

LEU2_YEAST  LEU2_ECOLI
FADH_YEAST  ADH3_ECOLI
ADH4_YEAST  ADH2_ECOLI
YME1_YEAST  FTSH_ECOLI

我只是好奇其他人会怎么做? 实际上,我的实际数据集将包含数千行,因此我想知道是否存在更有效的方式(无论是时间还是内存)? 或者人们如何添加“检查”以确保数字仅出现两次? 在这个阶段,我已经掌握了python基础知识,因此我正在寻找更好地设计代码的方法。

一种可能的改进是改变if line[0] not in Dict1.keys()if line[0] not in Dict1 ,由于not in Dict1.keys()是一个为O(n)的操作,而not in Dict是约O(1)。

我不确定真正的性能提升。 您应该花时间弄清楚这一点。

如果您的文件按第一行中的数字排序,则可以使用itertools.groupby

from itertools import groupby
import operator

with open(sys.argv[1]) as infile:
    # split lines and group them by the number in the first column
    groups= groupby([line.strip().split() for line in infile], operator.itemgetter(0))
# convert groups to lists and discard keys
groups= [list(lines) for _, lines in groups]
# discard groups that don't have 2 items and format the output
groups= ['%s\t%s'%(lines[0][4],lines[1][4]) for lines in groups if len(lines)==2]
# alternatively you can use
#   groups= ['\t'.join(zip(*lines)[4]) for lines in groups if len(lines)==2]

print '\n'.join(groups)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM