我有一个包含3列的excel数据文件。我将数据复制到文本板上以使用.txt(制表符分隔)代替.xls以便于数据解析。我想根据数字区间的第一个数字和"补码"对所有行进行排序。如果它们出现在数字间隔之前。我的数据如下(一些行有空的第3列行1,2,3,5,7,8,9,15):
81228..81500 Gene 22
81500..81856 Gene 17
complement(82256..84292) Gene 75
84307..85275 Gene 23 2.7.4.8
complement(97435..98067) Gene 91
complement(85325..86527) Gene 34 3.5.1.32
86756..87025 Gene 36
complement(92373..93341) Gene 45
88076..90292 Gene 34
complement(90289..92415) Gene 89 3.6.1.-
93492..94931 Gene 92 2.2.1.1
complement(97087..97347) Gene 12 2.7.7.6
complement(94928..97060) Gene 58 2.5.6.3, 3.1.8.2
79951..81162 Gene 3 1.7.1.2
complement(87022..87837) Gene 77
10..1008 Gene 500
100059..100178 Gene 501
100470..104660 Gene 502 6.3.5.5
100715..100861 Gene 503
101721..103604 Gene 504
101782..103698 Gene 505 1.1.1.49
1018..1137 Gene 506
10230..11636 Gene 507 6.3.1.2
102328..104049 Gene 508
10321..12651 Gene 509 2.3.1.16, 2.3.1.9
103256..104290 Gene 510
103607..104647 Gene 511
103658..104662 Gene 512 4.1.3.16, 4.1.2.14
103732..106095 Gene 513
104045..106027 Gene 514
104057..104305 Gene 515
10416..14087 Gene 516
104237..105262 Gene 517 3.1.11.2
我的预期输出:
79951..81162 Gene 3 1.7.1.2
81228..81500 Gene 22
81500..81856 Gene 17
84307..85275 Gene 23 2.7.4.8
86756..87025 Gene 36
88076..90292 Gene 34
93492..94931 Gene 92 2.2.1.1
complement(82256..84292) Gene 75
complement(85325..86527) Gene 34 3.5.1.32
complement(87022..87837) Gene 77
complement(90289..92415) Gene 89 3.6.1.-
complement(92373..93341) Gene 45
complement(94928..97060) Gene 58 2.5.6.3, 3.1.8.2
complement(97087..97347) Gene 12 2.7.7.6
complement(97435..98067) Gene 91
我尝试使用python如下:
import re
import sys
#import csv
pattern = '^complement\(\d+\.{2}\d+\)$'
#pattern = '^complement'
regexp = re.compile(pattern)
input_file = open('infile.txt', 'r')
output_file = open('outfile.txt','w')
for line in input_file:
item = line[0]
match = regexp.search(item)
if match:
output_file.writerow([line[0],\t,line1[1],\t, line[2]])
#output_file.writerow(line[0])
#del line[0], line[1], line[2], item
del output_file
我不确定如何从这里开始。有人可以帮忙!
答案 0 :(得分:2)
这应该可以正常工作,无需创建txt
文件。只需导入csv
:
In [23]: reader = csv.reader(open('tets.xls','rb'),delimiter='\t')
In [24]: f = list(reader)
In [25]: f #original file
Out[25]:
[['81228..81500', 'Gene', '22 '],
['81500..81856', 'Gene', '17 '],
['complement(82256..84292)', 'Gene', '75 '],
['84307..85275', 'Genne', '23', '2.7.4.8'],
['complement(97435..98067)', 'Gene', '91 '],
['complement(85325..86527)', 'Gene', '34', '3.5.1.32'],
['86756..87025', 'Gene', '36 '],
['complement(92373..93341)', 'Gene', '45 '],
['88076..90292', 'Gene', '34 '],
['complement(90289..92415)', 'Gene 89', '3.6.1.-'],
['93492..94931', 'Genne', '92', '2.2.1.1'],
['complement(97087..97347)', 'Gene', '12', '2.7.7.6'],
['complement(94928..97060)', 'Gene', '58', '2.5.6.3, 3.1.8.2'],
['79951..81162', 'Gene', '3', '1.7.1.2'],
['complement(87022..87837)', 'Gene', '77 ']]
In [26]: f.sort(key=lambda x: x[0])
In [27]: f #after sorting
Out[27]:
[['79951..81162', 'Gene', '3', '1.7.1.2'],
['81228..81500', 'Gene', '22 '],
['81500..81856', 'Gene', '17 '],
['84307..85275', 'Genne', '23', '2.7.4.8'],
['86756..87025', 'Gene', '36 '],
['88076..90292', 'Gene', '34 '],
['93492..94931', 'Genne', '92', '2.2.1.1'],
['complement(82256..84292)', 'Gene', '75 '],
['complement(85325..86527)', 'Gene', '34', '3.5.1.32'],
['complement(87022..87837)', 'Gene', '77 '],
['complement(90289..92415)', 'Gene 89', '3.6.1.-'],
['complement(92373..93341)', 'Gene', '45 '],
['complement(94928..97060)', 'Gene', '58', '2.5.6.3, 3.1.8.2'],
['complement(97087..97347)', 'Gene', '12', '2.7.7.
答案 1 :(得分:1)
这样的工作:
txt='''\
81228..81500 Gene 22
81500..81856 Gene 17
complement(82256..84292) Gene 75
84307..85275 Gene 23 2.7.4.8
complement(97435..98067) Gene 91
complement(85325..86527) Gene 34 3.5.1.32
86756..87025 Gene 36
complement(92373..93341) Gene 45
88076..90292 Gene 34
complement(90289..92415) Gene 89 3.6.1.-
93492..94931 Gene 92 2.2.1.1
complement(97087..97347) Gene 12 2.7.7.6
complement(94928..97060) Gene 58 2.5.6.3, 3.1.8.2
79951..81162 Gene 3 1.7.1.2
complement(87022..87837) Gene 77 '''
import re
lines=txt.splitlines()
print('\n'.join(sorted(lines, key=lambda s: re.search(r'^((?:\d+)|(?:complement\(\d+))', s).group(1))))
或者,如果它真的是分隔符,你可以松开正则表达式并执行:
txt='''\
81228..81500\tGene 22
81500..81856\tGene 17
complement(82256..84292)\tGene 75
84307..85275\tGene 23\t2.7.4.8
complement(97435..98067)\tGene 91
complement(85325..86527)\tGene 34\t3.5.1.32
86756..87025\tGene 36
complement(92373..93341)\tGene 45
88076..90292\tGene 34
complement(90289..92415)\tGene 89\t3.6.1.-
93492..94931\tGene 92\t2.2.1.1
complement(97087..97347)\tGene 12\t2.7.7.6
complement(94928..97060)\tGene 58\t2.5.6.3, 3.1.8.2
79951..81162\tGene 3\t1.7.1.2
complement(87022..87837)\tGene 77 '''
lines=txt.splitlines()
print('\n'.join(sorted(lines, key=lambda s: s.split('\t',1)[0])))
但是因为你要对第一个元素进行排序,所以根本不需要拆分它:
print('\n'.join(sorted(lines)))
以上任何情况,打印:
79951..81162 Gene 3 1.7.1.2
81228..81500 Gene 22
81500..81856 Gene 17
84307..85275 Gene 23 2.7.4.8
86756..87025 Gene 36
88076..90292 Gene 34
93492..94931 Gene 92 2.2.1.1
complement(82256..84292) Gene 75
complement(85325..86527) Gene 34 3.5.1.32
complement(87022..87837) Gene 77
complement(90289..92415) Gene 89 3.6.1.-
complement(92373..93341) Gene 45
complement(94928..97060) Gene 58 2.5.6.3, 3.1.8.2
complement(97087..97347) Gene 12 2.7.7.6
complement(97435..98067) Gene 91
您的一条评论指出,您希望计算数字的大小,而不仅仅是字典顺序。
您可以使用natural sort order来实现此目标:
import re
data='''\
81728..81500 Gene 22
81500..81856 Gene 17
complement(82256..84292) Gene 75
812..815 Gene 3 num
complement(822..842) Gene compliment 3 num75
811..815 Gene 3 num
'''
def alpha_num_sort(li):
def convert(s):
return int(s) if s.isdigit() else s
def key_func(key):
return tuple(convert(c) for c in re.split('([0-9]+)', key))
return sorted(li, key = key_func)
print '\n'.join(alpha_num_sort(data.splitlines()))
打印:
811..815 Gene 3 num
812..815 Gene 3 num
81500..81856 Gene 17
81728..81500 Gene 22
complement(822..842) Gene compliment 3 num75
complement(82256..84292) Gene 75
答案 2 :(得分:1)
我的两分钱:
import csv
# get a list of lines in the file
with open('in.txt') as in_file:
reader = csv.reader(in_file, delimiter = '\t')
lines = [line for line in reader]
lines.sort()
# generator to produce the desired output
lines = ('\n'.join(('\t'.join(line) for line in lines)))
with open('out.txt', 'w') as out_file:
out_file.write(lines)
使用键功能提取相关的排序参数 - 将上面的lines.sort()
替换为:
def key_func(line):
'''extract sorting parameters
line --> list
returns tuple
'''
key = line[0]
complement = 'complement' in key
# extract the interval
key = key[key.find('(') + 1 : key.find(')')]
# turn the interval into a 2 integer list
key = map(int, key.split('..'))
# return a tuple to sort on
return complement, key
lines.sort(key = key_func)
key_func
应返回您希望数据排序的值元组(按重要性排序)。如果您的实际数据与您发布的数据完全匹配,则会根据您的要求进行排序如果您的实际数据与发布的数据不完全匹配,则需要修改key_func
。