Python 总结文本文件的内容
我有一个类似以下示例的文本文件:Python 总结文本文件的内容,python,Python,我有一个类似以下示例的文本文件: chrX 7970000 8670000 3 2 7 RPS6KA6 4 chrX 7970000 8670000 3 2 7 7 SATL1 3 chrX 7970000 8670000 3 2 7 7 SH3BGRL 4 chrX 7970000 8670000 3 2 7 7 VCX2 1 chrX 86580000 86980000 1 1 5 KLHL4 2 chrX 87370000 88620000 4 11 CPXCR1 2 chrX 87370
chrX 7970000 8670000 3 2 7 RPS6KA6 4
chrX 7970000 8670000 3 2 7 7 SATL1 3
chrX 7970000 8670000 3 2 7 7 SH3BGRL 4
chrX 7970000 8670000 3 2 7 7 VCX2 1
chrX 86580000 86980000 1 1 5 KLHL4 2
chrX 87370000 88620000 4 11 CPXCR1 2
chrX 87370000 88620000 4 11 11 FAM9A 2
chrX 89050000 91020000 11 6 10 13 FAM9B 3
chrX 89050000 91020000 11 6 10 13 PABPC5 2
我想计算每行重复的时间(仅第1、第2和第3列
)。
在输出中
,将有5列
。前3列
将是相同的(每行仅重复一次),但在第4列
中,同一列和同一行中会有多个字符(这些字符位于原始文件
的第8列
)。5列
是原始文件中重复前3行的次数
简言之
:在输入文件
中,列4、5、6、7和9对输出文件无效。
我们应该计算前3列相同的行数
,因此,在输出文件中前3列将与输入文件相同
(但仅重复一次
)。5列是该行重复的次数。输出的4列
是重复行中的8列
中的所有字符。
在预期输出
中,此行被重复4次
:chrX 7970000 8670000
。因此,5列是4
,而4列是:RPS6KA6、SATL1、SH3BGRL、VCX2
。如您所见,第4列中的字符是逗号分隔的
以下是预期输出:
chrX 7970000 8670000 RPS6KA6、SATL1、SH3BGRL、VCX2 4
chrX 86580000 86980000 KLHL4 1
chrX 87370000 88620000 CPXCR1,FAM9A 2
chrX 89050000 91020000 FAM9B,PABPC5 2
我正试图用Python实现这一点,并编写了以下代码:
file = open("myfile.txt", 'rb')
infile = []
for line in file:
infile.append(line)
count = 0
final = []
for i in range(len(infile)):
count += 1
if infile[i-1] == infile[i]
final.append(infile[0,1,2,7, count])
这段代码没有返回我想要的。您知道如何修复它吗?这应该可以满足您的需要:
from collection import defaultdict # 1
lines = [line.rstrip().split() for line in open('file.txt').readlines()] # 2
counter = defaultdict(list) # 3
for line in lines:
counter[(line[0], line[1], line[2])].append(line[7]) # 4
for key, value in counter.iteritems(): # 5
print '{} {} {}'.format(' '.join(key), ','.join(value), len(value)) # 6
说明:
我们将使用一个方便的库,它为我们提供一个带有默认值的字典
读取整个输入文件,删除末尾的新行并拆分为多个部分(在空白处)
为任何键创建一个默认值为空列表的字典
通读这些行并填充字典
第1-3列是关键
对于第8列中的每个字符序列,我们将其附加到列表中(如果我们没有将defaultdict
与list
一起使用,这将更加复杂)
迭代字典的键值对
打印输出,将数据结构连接到所需格式
希望这有助于另一种解决方案:
from collections import defaultdict
summary = defaultdict(list)
# Input and collate
with open('myfile.txt', 'r') as fp:
for line in fp:
items = line.strip().split()
key, data = (items[0], items[1], items[2]), items[7]
summary[key].append(data)
# Output
for keys, entries in summary.items():
print('{keys}\t{entries} {count}'.format(
keys=' '.join(keys),
entries=','.join(entries),
count=len(entries) ))
对于Python2.7,这将生成输出
chrX 7970000 8670000 RPS6KA6,SATL1,SH3BGRL,VCX2 4
chrX 89050000 91020000 FAM9B,PABPC5 2
chrX 87370000 88620000 CPXCR1,FAM9A 2
chrX 86580000 86980000 KLHL4 1
对于Python 3.6,输出为:
chrX 7970000 8670000 RPS6KA6,SATL1,SH3BGRL,VCX2 4
chrX 86580000 86980000 KLHL4 1
chrX 87370000 88620000 CPXCR1,FAM9A 2
chrX 89050000 91020000 FAM9B,PABPC5 2
两个Python版本的输出顺序不同,因为Python 3.6中的字典(扩展名为defaultdicts)保留了插入键的顺序。
从你的描述中不清楚订购是否重要
我认为您的版本不起作用的主要原因是您的表达式:infle[0,1,2,7,count]
不符合您的想法
似乎您希望从行中提取第0、第1、第2和第7列。然而,这在Python中不是有效的索引符号,Python也不知道数据中的列——它只知道字符
在我的版本中,我在每一行上使用“拆分”方法-这将根据空格/制表符的位置分隔行-即将数据拆分为列。这是一个很好的使用机会。您可以按如下方式打开文件:
import pandas as pd
# open file
df = pd.read_csv('myfile.txt`)
# group and apply functions
df = df.groupby([0,1,2])[7].agg([('count', 'size'),
('genes', lambda col: ', '.join(col))
]).reset_index()
# rename columns
df = df.rename({0: 'chromosome', 1: 'start_region', 2: 'end_region'}, axis=1)
# save new file
df.to_csv('newfile.txt', sep='\t', index=False, header=True)
0 1 2 3 4 5 6 7 8
0 chrX 7970000 8670000 3 2 7 7 RPS6KA6 4
1 chrX 7970000 8670000 3 2 7 7 SATL1 3
2 chrX 7970000 8670000 3 2 7 7 SH3BGRL 4
3 chrX 7970000 8670000 3 2 7 7 VCX2 1
4 chrX 86580000 86980000 1 1 1 5 KLHL4 2
5 chrX 87370000 88620000 4 4 11 11 CPXCR1 2
6 chrX 87370000 88620000 4 4 11 11 FAM9A 2
7 chrX 89050000 91020000 11 6 10 13 FAM9B 3
8 chrX 89050000 91020000 11 6 10 13 PABPC5 2
这将创建如下所示的数据帧:
import pandas as pd
# open file
df = pd.read_csv('myfile.txt`)
# group and apply functions
df = df.groupby([0,1,2])[7].agg([('count', 'size'),
('genes', lambda col: ', '.join(col))
]).reset_index()
# rename columns
df = df.rename({0: 'chromosome', 1: 'start_region', 2: 'end_region'}, axis=1)
# save new file
df.to_csv('newfile.txt', sep='\t', index=False, header=True)
0 1 2 3 4 5 6 7 8
0 chrX 7970000 8670000 3 2 7 7 RPS6KA6 4
1 chrX 7970000 8670000 3 2 7 7 SATL1 3
2 chrX 7970000 8670000 3 2 7 7 SH3BGRL 4
3 chrX 7970000 8670000 3 2 7 7 VCX2 1
4 chrX 86580000 86980000 1 1 1 5 KLHL4 2
5 chrX 87370000 88620000 4 4 11 11 CPXCR1 2
6 chrX 87370000 88620000 4 4 11 11 FAM9A 2
7 chrX 89050000 91020000 11 6 10 13 FAM9B 3
8 chrX 89050000 91020000 11 6 10 13 PABPC5 2
现在,使用内置函数,我们可以在列[0,1,2]
上使用groupby
,并在组上应用函数,从而:
0 1 2 count genes
0 chrX 7970000 8670000 4 RPS6KA6, SATL1, SH3BGRL, VCX2
1 chrX 86580000 86980000 1 KLHL4
2 chrX 87370000 88620000 2 CPXCR1, FAM9A
3 chrX 89050000 91020000 2 FAM9B, PABPC5
这样做的目的是将数据分组并添加我们感兴趣的列:
('count','size')
使用函数创建列count
('genes',lambda col:','.join(col))
使用刚刚将分组列连接在一起的lambda
函数创建列genes
这是最终文件的外观:
chromosome start_region end_region count genes
chrX 7970000 8670000 4 RPS6KA6, SATL1, SH3BGRL, VCX2
chrX 86580000 86980000 1 KLHL4
chrX 87370000 88620000 2 CPXCR1, FAM9A
chrX 89050000 91020000 2 FAM9B, PABPC5
如果您有任何问题,请访问。snap-除非我逐行执行,而不是一次读取整个文件。根据Python版本的不同,不同排序顺序的解释很好!:)