[英]Comparing two csv files using Python and find similar values in two file and save the similar values in another file as matching values
[英]How to read two files in a for-loop and update values in one files based on matching-values in another file?
我想通過同時讀取兩個文件來更新列中的值。
main_file具有以下數據:
contig pos GT PGT_phase PID PG_phase PI
2 1657 ./. . . ./. .
2 1738 0/1 . . 0|1 935
2 1764 0/1 . . 1|0 935
2 1782 0/1 . . 0|1 935
2 1850 0/0 . . 0/0 .
2 1860 0/1 . . 1|0 935
2 1863 0/1 . . 0|1 935
2 2969 0/1 . . 1|0 3352
2 2971 0/0 . . 0/0 .
2 5207 0/1 0|1 5185 1|0 1311
2 5238 0/1 . . 0|1 1311
2 5241 0/0 . . 0/0 .
2 5258 0/1 . . 1|0 1311
2 5260 0/0 . . 0/0 .
2 5319 0/0 . . 0/0 .
2 5398 0/1 0|1 5398 1|0 1311
2 5403 0/1 0|1 5398 1|0 1311
2 5426 0/1 0|1 5398 1|0 1311
2 5427 0/1 0|1 5398 0/1 .
2 5434 0/1 0|1 5398 1|0 1311
2 5454 0/1 0|1 5398 0/1 .
2 5457 0/0 . . 0/0 .
2 5467 0/1 0|1 5467 0|1 1311
2 5480 0/1 0|1 5467 0|1 1311
2 5483 0/0 0|1 5482 0/0 .
2 6414 0/1 . . 0|1 1667
2 6446 0/1 0|1 6446 0|1 1667
2 6448 0/1 0|1 6446 0|1 1667
2 6465 0/1 0|1 6446 0|1 1667
2 6636 0/1 . . 1|0 1667
2 6740 0/1 . 6740 0|1 1667
2 6748 0/1 . 6740 0|1 .
另一個match_file具有以下類型的信息:
**PI PID**
1309 3617741,3617753,3617788,3618156,3618187,3618289
131 11793586
1310
1311 5185,5398,5467,5576
1312 340692,340728
1313 18503498
1667 6740,12237,12298
我正在嘗試做的是:
更新的工作方式:
new_PI value = main_PI
然后continue
main_PI
和main_PID
均為.
, new_PI = .
並continue
new_PI = PI_match_file
,然后continue
我寫了下面的代碼:
main_file = open("2ms01e_chr2_table.txt", 'r+')
match_file = open('updated_df_table.txt', 'r+')
main_header = main_file.readline()
match_header = match_file.readline()
main_data = main_file.read().rstrip('\n').split('\n')
match_data = match_file.read().rstrip('\n').split('\n')
file_update = open('PI_updates.txt', 'w')
file_update.write('contig pos GT PGT_phase PID PG_phase PI new_PI\n')
file_update.close()
for line in main_data:
main_column = line.split('\t')
PID_main = main_column[4]
PI_main = main_column[6]
if PID_main == '.' and PI_main == '.':
new_PI = '.'
continue
if PI_main != '.':
new_PI = PI_main
continue
if PI_main == '.' and PID_main != '.':
for line in match_data:
match_column = line.split('\t')
PI_match = match_column[0]
PID_match = match_column[1].split(',')
if PID_main in PID_match:
new_PI = PI_match
continue
file_update = open('PI_updates.txt', 'a')
file_update.write(line + '\t' + str(new_PI)+ '\n')
file_update.close()
我沒有收到任何錯誤,但是看起來我沒有編寫適當的代碼來讀取兩個文件。
我的輸出應該是這樣的:
contig pos GT PGT PID PG PI new_PI
2 5426 0/1 0|1 5398 1|0 1311 1311
2 5427 0/1 0|1 5398 0/1 . 1311
2 5434 0/1 0|1 5398 1|0 1311 1311
2 5454 0/1 0|1 5398 0/1 . 1311
2 5457 0/0 . . 0/0 . .
2 5467 0/1 0|1 5467 0|1 1311 1311
2 5480 0/1 0|1 5467 0|1 1311 1311
2 5483 0/0 0|1 5482 0/0 1667 1667
2 5518 1/1 1|1 5467 1/1 . 1311
2 5519 0/0 . . 0/0 . .
2 5547 1/1 1|1 5467 1/1 . 1311
2 5550 ./. . . ./. . .
2 5559 1/1 1|1 5467 1/1 . 1311
2 5561 0/0 . . 0/0 . .
2 5576 0/1 0|1 5576 1|0 1311 1311
2 5599 0/1 0|1 5576 1|0 1311 1311
2 5602 0/0 . . 0/0 . .
2 5657 0/1 . . 1|0 1311 1311
2 5723 0/1 . . 1|0 1311 1311
2 6414 0/1 . . 0|1 1667 1667
2 6446 0/1 0|1 6446 0|1 1667 1667
2 6448 0/1 0|1 6446 0|1 1667 1667
2 6465 0/1 0|1 6446 0|1 1667 1667
2 6636 0/1 . . 1|0 1667 1667
2 6740 0/1 . 6740 0|1 1667 1667
2 6748 0/1 . 6740 0|1 . 1667
提前致謝 !
您的代碼看起來不錯,除了您的代碼通常不會到達附加PI_update文件的行。 continue
語句終止循環迭代,移至下一個迭代,從而跳過文件寫入行。 如果輸入第三個if語句則不是這種情況,因為那么continue語句只會終止內部循環。
有點相關,我為您贏得了快速的勝利:您有兩個for循環堆疊。 相反,您可以通過在字典中查找來替換match_data
的迭代。 這可以極大地提高較大文件的速度。 另外,您可能希望將new_PI值存儲在列表中,並在代碼末尾執行一次寫入操作。 文件I / O通常非常注重性能,因此應盡可能少地進行。
編輯:(示例)
main_data = main_file.read().rstrip('\n').split('\n')
match_data = match_file.read().rstrip('\n').split('\n')
match_map = {} # instantiate empty dict
for line in match_data:
PI, PIDs = line.split('\t')
# update the dict with all the PIDs from this line
match_map.update({PID:PI for PID in PIDs})
PI_updates = 'contig\tpos\tGT\tPGT_phase\tPID\tPG_phase\tPI\tnew_PI\n'
for line in main_data:
_, _, _, PID, _, PI = line.split('\t')
if PID_main == '.' and PI_main == '.':
new_PI = '.'
elif PI_main != '.':
new_PI = PI_main
else:
# dict.get(key, default) returns default if key doesn't return a value
new_PI = match_map.get(PID, 'no match found')
# append the result to the PI_updates string
PI_updates += line + '\t' + str(new_PI)+ '\n'
# let with statement take care of closing the file
with open('PI_updates.txt', 'w') as file_update:
file_update.write(PI_updates)
我本該使用break
而不是continue
。 另外,在其他地方繼續也無濟於事。
main_file = open("2ms01e_chr2_table.txt", 'r+')
match_file = open('updated_df_table.txt', 'r+')
main_header = main_file.readline()
match_header = match_file.readline()
print(match_header, "\n**")
main_data = main_file.read().rstrip('\n').split('\n')
match_data = match_file.read().rstrip('\n').replace('[', '')\
.replace("'", "").replace(']', '').replace(" ", '')
match_data = match_data.split('\n')
file_update = open('PI_updates.txt', 'w')
file_update.write('contig pos GT PGT_phase PID PG_phase PI new_PI\n')
file_update.close()
for line in main_data:
main_column = line.split('\t')
PID_main = main_column[4]
PI_main = main_column[6]
chrom = main_column[0]
pos = main_column[1]
if PID_main == '.' and PI_main == '.':
new_PI = '.'
if PI_main != '.':
new_PI = PI_main
elif PI_main == '.' and PID_main != '.':
for line1 in match_data:
match_column = line1.split('\t')
PI_match = match_column[0]
PID_match = match_column[1].split(',')
if PID_main in PID_match:
new_PI = PI_match
break
elif PID_main not in PID_match:
new_PI = str(chrom) + '_' + str(PID_main)
file_update = open('PI_updates.txt', 'a')
file_update.write(line + '\t' + str(new_PI)+ '\n')
file_update.close()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.