如何使用 Python 修改 tsv 文件列
How to modify a tsv-file column with Python
我有一个 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 列。
你知道如何解决这个问题吗?谢谢大家
您可以将 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;
如果你只想用@替换第一次出现的_,你可以这样做,而不需要将你的文件作为数据帧加载,也不需要使用任何第三方库,比如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)
这将 return 行 其中包含
## 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;
我有一个 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 列。
你知道如何解决这个问题吗?谢谢大家
您可以将 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;
如果你只想用@替换第一次出现的_,你可以这样做,而不需要将你的文件作为数据帧加载,也不需要使用任何第三方库,比如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)
这将 return 行 其中包含
## 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;