【问题标题】:How to modify a tsv-file column with Python如何使用 Python 修改 tsv 文件列
【发布时间】:2021-10-22 17:59:21
【问题描述】:

我有一个 GFF3 文件(主要是一个有 9 列的 TSV 文件),我正在尝试在我的文件的第一列中进行一些更改,以便覆盖对文件本身的修改。

GFF3 文件如下所示:

## GFF3 file
## replicon1
## replicon2
replicon_1  prokka  gene    0   15  .   @   .   ID=some_gene_1;
replicon_1  prokka  gene    40  61  .   @   .   ID=some_gene_1;
replicon_2  prokka  gene    8   32  .   @   .   ID=some_gene_2;
replicon_2  prokka  gene    70  98  .   @   .   ID=some_gene_2;

我写了几行代码,其中我决定更改某个符号(例如“_”)和要替换的符号(例如“@”):

import os
import re
import argparse
import pandas as pd

def myfunc() -> tuple:
    ap.add_argument("-f", "--file", help="path to file")
    ap.add_argument("-i", "--input_word",help="Symbol to delete")
    ap.add_argument("-o", "--output_word", help="Symbol to insert")
    return ap.parse_args()
args = myfunc()
my_file = args.file
in_char = args.input_word
out_char = args.output_word

with open (my_file, 'r+') as f:
    rawfl = f.read()
    rawfl = re.sub(in_char, out_char, rawfl)
    f.seek(0)
    f.write(rawfl)
    f.close()

输出是这样的:

## GFF3 file
## replicon1
## replicon2
replicon@1  prokka  gene    0   15  .   @   .   ID=some@gene@1;
replicon@1  prokka  gene    40  61  .   @   .   ID=some@gene@1;
replicon@2  prokka  gene    8   32  .   @   .   ID=some@gene@2;
replicon@2  prokka  gene    70  98  .   @   .   ID=some@gene@2;

如您所见,“@”中的所有“_”都已更改。 我尝试使用pandas 修改脚本,以便仅将修改应用于第一列(seqid,如下所示):

with open (my_file, 'r+') as f:
    genomic_dataframe = pd.read_csv(f, sep="\t", names=['seqid', 'source', 'type', 'start', 'end', 'score', 'strand', 'phase', 'attributes'])
    id = genomic_dataframe.seqid
    id = str(id) #this is used because re.sub expects strings, not dataframe
    id = re.sub(in_char, out_char, genid)
    f.seek(0)
    f.write(genid)
f.close()

我没有获得预期的结果,而是像 seqid 列(已正确修改)添加到文件但未覆盖原始的。

我想要得到的是这样的:

## GFF3 file
## replicon1
## replicon2
replicon@1  prokka  gene    0   15  .   @   .   ID=some_gene_1;
replicon@1  prokka  gene    40  61  .   @   .   ID=some_gene_1;
replicon@2  prokka  gene    8   32  .   @   .   ID=some_gene_2;
replicon@2  prokka  gene    70  98  .   @   .   ID=some_gene_2;

其中“@”符号仅出现在第一列,而“_”则保留在第 9 列。

你知道如何解决这个问题吗?谢谢大家。

【问题讨论】:

    标签: python pandas dataframe argparse re


    【解决方案1】:

    如果您只想将第一次出现的 _ 替换为 @,您可以这样做,而无需将文件作为数据框加载,也无需使用任何 3rd 方库,例如 pandas强>.

    with open('f') as f:
        lines = [line.rstrip() for line in f]
    
    for line in lines:
        # Ignore comments
        if line[0] == '#':
            continue
        line = line.replace('_', '@', 1)
    

    这将返回 lines 其中包含

    ## GFF3 file
    ## replicon1
    ## replicon2
    replicon@1  prokka  gene    0   15  .   @   .   ID=some_gene_1;
    replicon@1  prokka  gene    40  61  .   @   .   ID=some_gene_1;
    replicon@2  prokka  gene    8   32  .   @   .   ID=some_gene_2;
    replicon@2  prokka  gene    70  98  .   @   .   ID=some_gene_2;
    

    【讨论】:

    • 它可以工作,但不会覆盖原始列,它会添加一个具有更正字符的新列。我想用新符号完全替换原始文件的列。
    【解决方案2】:

    您可以将re.sub 与以^(字符串的开头)开头的模式一起使用+ 在re.sub 中使用lambda 函数。例如:

    import re
    
    # change only first column:
    r = re.compile(r"^(.*?)(?=\s)")
    
    in_char = "_"
    out_char = "@"
    
    with open("input_file.txt", "r") as f_in, open("output_file.txt", "w") as f_out:
        for line in map(str.strip, f_in):
            # skip empty lines and lines starting with ##
            if not line or line.startswith("##"):
                print(line, file=f_out)
                continue
    
            line = r.sub(lambda g: g.group(1).replace(in_char, out_char), line)
            print(line, file=f_out)
    

    创建output_file.txt:

    ## GFF3 file
    ## replicon1
    ## replicon2
    replicon@1  prokka  gene    0   15  .   @   .   ID=some_gene_1;
    replicon@1  prokka  gene    40  61  .   @   .   ID=some_gene_1;
    replicon@2  prokka  gene    8   32  .   @   .   ID=some_gene_2;
    replicon@2  prokka  gene    70  98  .   @   .   ID=some_gene_2;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-29
      • 2014-05-15
      • 2013-05-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多