簡體   English   中英

如何在for循環中讀取兩個文件並根據另一個文件中的匹配值更新一個文件中的值?

[英]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

我正在嘗試做的是:

  • 我想創建一個具有更新的PI值新列(new_PI)

更新的工作方式:

  • 因此,如果在main_file的行中有一個PI值,則它很簡單: new_PI value = main_PI然后continue
  • 如果在main_file中,main_PImain_PID均為. new_PI = . continue
  • 但是,如果PI值為“。” 但是PID值是一些整數 ,現在我們在match_file中查找在PID列表中包含該值的PI值。 如果找到匹配的PID,則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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM