Python初学者。我有一个看起来像这样的文件(每个字段都是\ t分隔):
chr1_1792868_SNP Bcin01g04980 NON_SYNONYMOUS NON_SYNONYMOUS[T](gene:Bcin01g04980|transcript:Bcin01g04980.1|P->S:225) ...
chr1_1792869_SNP Bcin01g04980 NON_SYNONYMOUS NON_SYNONYMOUS[T](gene:Bcin01g04980|transcript:Bcin01g04980.1|P->L:225) ...
chr2_19719_SNP Bcin02g00005 SYNONYMOUS SYNONYMOUS[A](gene:Bcin02g00005|transcript:Bcin02g00005.1) ...
chr2_19811_SNP Bcin02g00005 SYNONYMOUS SYNONYMOUS[A](gene:Bcin02g00005|transcript:Bcin02g00005.1) ...
chr2_20024_SNP Bcin02g00005 NON_SYNONYMOUS NON_SYNONYMOUS[C](gene:Bcin02g00005|transcript:Bcin02g00005.1|S->A:331)
chr2_20025_SNP Bcin02g00005 SYNONYMOUS SYNONYMOUS[A](gene:Bcin02g00005|transcript:Bcin02g00005.1)
我想解析文件并一次比较2行,并比较它们之间的值。
所以在这种情况下,我想比较第1行和第2行,检查是否有" SYNONYMOUS"在每个人的第3个领域。如果是的话,我会做一些事情,如果没有(这种情况)我继续前进到第3和第4行(这次比较两个" SYNONYMOUS"值为正),我会选择该行的第一个值做了更多的事情(与另一个词典比较)。
我想做类似的事情:
with open ('file.txt') as mutmut_mutants:
for line1 in mutmut_mutants:
line2 = next(mutmut_mutants)
print type(line1)
print line2+ "line2"
但问题是我正在处理字符串而不是列表元素(在大列表中的行/元素上)。处理列表似乎比使用字符串/正则表达式更容易。然后我想到了这个:
with open ('file.txt') as mutmut_mutants:
for i in csv.reader(mutmut_mutants, delimiter='\t'):
for k,(l1, l2) in enumerate(zip(i[0::2], i[1::2])):
print str(zip(i[0::2], i[1::2]))
但是我无法让它发挥作用(而且我不能很清楚地获得拉链和i [0 :: 2])。我要做的是:比较第2行和第2行,如果两行中的SYNONYMOUS获得每行的第一个字符串(chrX_XXXXX_SNP)。
有关我应该如何进行的任何想法?
答案 0 :(得分:0)
我认为你要找的是字符串的split方法。像在第一个代码示例中一样遍历文件,然后使用以下选项分隔选项卡上的每一行:
ls = []
with open ('file.txt') as mutmut_mutants:
for line1 in mutmut_mutants:
fields = line1.split('\t')
ls.append(fields)
拆分选项卡上的字符串将为您提供由制表符分隔的每个字段的列表。然后,您可以将其附加到列表中,然后根据需要进行处理。因此,例如,要访问第四行的第三个字段,您只需ls[3][2]
。希望这会有所帮助。
答案 1 :(得分:0)
它可能取决于你的文本文件的重量(你可以拥有非常多的SNP ......)。
如果您可以将整个文件加载到一个变量中:
# Store everything in one variable - readlines() to have a list of lines
mutmut_mutants = open('file.txt', "r").readlines()
# The number of lines
n = len(mutmut_mutants)
# Loop two by two (end at n-1 or n-2)
for i in range(0, n-1, 2):
first_line = mutmut_mutants[i]
second_line = mutmut_mutants[i+1]
# Split those lines (the separator is \t ?) and compare what's
# inside, for example
syn1 = first_line.split("\t")[2]
syn2 = second_line.split("\t")[2]
if syn1 == syn2 and syn1 == "SYNONYMOUS":
# Do stuff
如果您无法在一个变量中加载所有内容。哼。我可能无法提出一些甚至非常漂亮的东西。希望这会有所帮助。
答案 2 :(得分:0)
你有一个迭代器,一次产生1个项目,即文件对象。
你需要一个包装那个并一次生成2个项目的迭代器。
这是一种天真的方法:
def even_by_two(incoming):
while True:
one = next(incoming)
two = next(incoming)
yield (one, two)
# This will break on a StopIteration exception,
# which is ok for a generator.
# The odd item at the end will be silently missed.
演示:
with open('/etc/passwd') as f:
for one, two in even_by_two(f):
print ("one -> ", one)
print ("two -> ", two)
问题当然是,如果行数不均匀,最后一行将会丢失。
这是一种不那么天真的方法,它通过给定大小的块来切割输入迭代器;最后一个块可以更小。
def by_n(how_much, incoming):
while True: # We need a post-condition, got no do-while in Python.
result = []
count = 0
# The `for` will advance the iterator, but not past its end.
for value in incoming:
result.append(value)
count += 1
if count >= how_much:
break
if result:
yield result
else: # We got nothing from the iterator, it must be over.
break
>>> list(by_n(2, iter('abcdefg')))
[['a', 'b'], ['c', 'd'], ['e', 'f'], ['g']]
>>> list(by_n(5, iter('abcdefg')))
[['a', 'b', 'c', 'd', 'e'], ['f', 'g']]
请注意,输入必须是生成器/迭代器,例如一个文件,或csv.reader
。一个简单的列表或字符串将不起作用,因此上面的iter(...)
会生成一个迭代器。
答案 3 :(得分:0)
使用csv.reader
是一种更好的解析CSV文件的方法,而不是手动执行。但是,您可以显式使用迭代器,而不是使用for
循环,就像使用file
对象一样。
with open ('file.txt') as mutmut_mutants:
reader = csv.reader(mutmut_mutants, delimiter='\t')
while True:
try:
l1 = next(reader)
l2 = next(reader)
except StopIteration:
pass
# Use l1 and l2 here
答案 4 :(得分:0)
您可以使用pandas
模块将文件作为数据框读取(尽管您可能在排序列名时遇到一些麻烦。
假设你不熟悉大熊猫(把它放在你要学习的东西的清单上,对于任何与数据相关的东西都很值得),你可以试试这样的东西:
with open('file.txt') as f:
data = f.readlines()
indexes = []
for i, line in enumerate(data[:-1]):
if (line.split(' ')[2] == data[i+1].split(' ')[2]) and line.split(' ')[2] == 'SYNONYMOUS':
indexes.append(i)
for i in indexes:
print data[i], data[i+1] # or do whatever you want with those
索引是文件中每对符合条件的第一行的位置列表。
根据你想做的事情,pandas可能是更好的方式(这只是一个猜测,因为我不能将你的例子加载到pandas中,因为行的长度不同(由于......) )
import pandas as pd
df = pd.read_csv('file.txt', sep='\t', header=0) # might be header=None
df.columns=['mutation', 'strain', 'syn', 'info']
match_df = df.loc[df['syn'] == df['syn'].shift(1)] # might need to specify axis= for .shift
这将为您提供(再次)每对中第一个的数据帧。
答案 5 :(得分:0)
你可以制作两个数组并存储当前行和前一行:
list = []
list_before =[]
with open ('file.txt', 'r') as mutmut_mutants:
list.append(mutmut_mutants.readline().split())
print(list)
然后比较当前和前一个列表在同一位置是否为SYNNONYMOUS。
print(list[0][0][:3]) = "cnr"
print(list[0][0][-4:]) = "_SNP"
希望如果有帮助