基于一列匹配文件
Matching files based on one column
我有表格中的数据
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 不会比 match 5000 好。我该怎么做?
希望这能给您一个好的开始。我刚刚将文件命名为 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")
我确信这可以提高效率。它循环遍历第二个字典的次数与第一个字典中的索引数一样多。此外,我已将 return 的匹配数设置为 2,以便使用问题中的微小数据集进行测试。你可以赚到 5,000 或任何你喜欢的。列表中的元素不是随机的,但我也没有强加任何超出列表自然构建的顺序。 (编辑:不再正确......它现在打乱列表。)我还改变了匹配阈值,以防你想稍微探索其他值。
这是我认为以相当有效的方式完成您想要的事情的东西,因此希望能很好地扩大规模。您没有说明您使用的是哪个版本的 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
我有表格中的数据
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 不会比 match 5000 好。我该怎么做?
希望这能给您一个好的开始。我刚刚将文件命名为 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")
我确信这可以提高效率。它循环遍历第二个字典的次数与第一个字典中的索引数一样多。此外,我已将 return 的匹配数设置为 2,以便使用问题中的微小数据集进行测试。你可以赚到 5,000 或任何你喜欢的。列表中的元素不是随机的,但我也没有强加任何超出列表自然构建的顺序。 (编辑:不再正确......它现在打乱列表。)我还改变了匹配阈值,以防你想稍微探索其他值。
这是我认为以相当有效的方式完成您想要的事情的东西,因此希望能很好地扩大规模。您没有说明您使用的是哪个版本的 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