我的数据格式为“
rsID MAF
rs1980123 0.321
rs870123 0.142
rs314234 0.113
rs723904 0.022
rs1293048 0.098
rs1234123 0.314
rs239401 0.287
rs0928341 0.414
rs9038241 0.021
rs3801423 0.0712
rs8041239 0.312
这个文件长约2,000行。我在表单中有另一个数据文件。该文件大约有700万行:
rsID iHS Fst MAF
rs701234 1.98 0.11 0.098
rs908341 1.32 0.31 0.189
rs101098 0.315 0.08 0.111
rs100981 0.093 0.123 0.023
rs7345123 0.481 0.20 0.479
rs090321 1.187 0.234 0.109
rs512341 1.89 0.092 0.324
我想根据它们的MAF是否在彼此的+/- 0.05之内,将rsID改为第一列。 rsID列来自第一个数据,然后匹配列来自第二个数据。这些匹配基于+/- MAF 0.05。输出看起来像:
rsID match
rs1980123 rs512341
rs870123 rs101098
rs314234 rs090321
rs723904 rs100981
rs1293048 rs701234
我实际上希望输出看起来像(有5,000列):
rsID match1 match2 match3
... ... ... ...
... ... ... ...
... ... ... ...
我希望它尽可能随机,以便match1不比匹配5000好。我怎么能这样做?
答案 0 :(得分:1)
希望这会给你一个良好的开端。我刚刚调用了文件file1
和file2
。非常有创意,我知道。
import random
f1_dict = {}
f2_dict = {}
match_dict = {}
match_threshold = .05
matches_to_return = 2
skip_unmatched = True
isfirstline = True
for line in open("file1"):
if isfirstline:
isfirstline = False
continue
f1_dict[line.split()[0]] = line.split()[1]
isfirstline = True
for line in open("file2"):
if isfirstline:
isfirstline = False
continue
f2_dict[line.split()[0]] = line.split()[3]
for i in f1_dict:
compare_rsID = i
compare_val = f1_dict[i]
temp_list = []
for j in f2_dict:
if abs(float(f2_dict[j]) - float(compare_val)) <= match_threshold:
temp_list.append(j)
match_dict[i] = temp_list
fo = open("output.txt", "wb")
for k in match_dict:
if skip_unmatched and len(match_dict[k]) == 0:
continue
else:
random.shuffle(match_dict[k])
fo.write(k),
for l in match_dict[k][:matches_to_return]:
fo.write(" ")
fo.write(l),
fo.write("\n")
我确信这可以提高效率。它循环通过第二个字典,与第一个字典中的索引一样多次。此外,我已将匹配数设置为2,以便使用问题中的微小数据集进行测试。你可以赚5000或任何你喜欢的。列表中的元素不是随机的,但我也没有在列表的自然构建之外强加任何顺序。 (编辑:不再是真的......它现在改变了列表。)我还调整了匹配阈值,以防你想要探索其他值。
答案 1 :(得分:1)
在这里,我认为以一种相当有效的方式做你想要的东西,所以希望能够很好地扩大规模。您没有说出您正在使用的Python版本,因此它已编写为与2.x版一起使用。用于创建输出文件的字段分隔符是一个变量,因此可以轻松更改。
匹配数量不限于5,000 - 它会全部找到 - 但如果真的有必要,可以添加强制限制。
from collections import defaultdict
TOLERANCE = 0.05
DELIM = '\t'
ref_dict = {}
with open('second_file.txt', 'rt') as inf:
next(inf) # skip header row
for line in inf:
fields = line.split()
ref_dict[fields[0]] = float(fields[3]) # rsID to MAF
matches = defaultdict(list)
with open('first_file.txt', 'rt') as inf:
next(inf) # skip header row
for line in inf:
fields = line.split()
rsID, MAF = fields[0], float(fields[1])
for ref_id, ref_value in ref_dict.iteritems():
if abs(MAF-ref_value) <= TOLERANCE:
matches[rsID].append(ref_id)
# determine maximum number of matches for output file header row
longest = max(map(len, (v for v in matches.itervalues())))
with open("output.txt", "wt") as outf:
outf.write('rsId' + DELIM + DELIM.join('match%d' % i
for i in xrange(1, longest+1)) + '\n')
fmt_str = '{}' + DELIM + '{}\n'
for k,v in matches.iteritems():
outf.write(fmt_str.format(k, (DELIM.join(v))))
根据问题中显示的示例数据生成的output.txt
内容(»
代表制表符):
rsId» match1» match2» match3» match4
rs870123» rs908341» rs090321» rs701234» rs101098
rs9038241» rs100981
rs1234123» rs512341
rs1293048» rs090321» rs701234» rs101098
rs723904» rs100981
rs1980123» rs512341
rs3801423» rs090321» rs701234» rs101098» rs100981
rs8041239» rs512341
rs239401» rs512341
rs314234» rs090321» rs701234» rs101098