删除文件每行中不需要的字符,然后在Python中将剩下的字符与另一个文件进行匹配
我想编写一个python脚本来解决以下问题: 我有两个标签分开的文件,一个只有一列各种各样的单词。另一个文件有一列包含类似单词,以及其他信息。但是,在第一个文件中,有些行包含多个单词,以“//”分隔。另一个文件也有类似的问题,但分隔符是“|” 文件#1删除文件每行中不需要的字符,然后在Python中将剩下的字符与另一个文件进行匹配,python,matching,Python,Matching,我想编写一个python脚本来解决以下问题: 我有两个标签分开的文件,一个只有一列各种各样的单词。另一个文件有一列包含类似单词,以及其他信息。但是,在第一个文件中,有些行包含多个单词,以“//”分隔。另一个文件也有类似的问题,但分隔符是“|” 文件#1 RED BLUE /// GREEN YELLOW /// PINK /// PURPLE ORANGE BROWN /// BLACK 文件#2(包含其他测量值的附加列) 我想解析每个文件并匹配相同的单词,然后再附加额外度量的列。但是我想忽略
RED
BLUE /// GREEN
YELLOW /// PINK /// PURPLE
ORANGE
BROWN /// BLACK
文件#2(包含其他测量值的附加列)
我想解析每个文件并匹配相同的单词,然后再附加额外度量的列。但是我想忽略第一个文件中的//
,第二个文件中的|
,这样每个单词都可以单独与其他列表进行比较。输出文件应该只有两个列表中出现的任何单词的一列,然后是文件2中附加的附加信息。有什么帮助吗
添加信息/更新: 这里有8行文件#1,我使用了上面的颜色名称使其更简单,但这就是单词的真正含义:这些是“符号”: 这里有一行文件#2:我需要运行文件1中的每个符号,看看它是否与文件2中第5列中的任何一个“同义词”匹配(这里的同义词是A1B | ABG | GAP | HYST2477)。如果file1中的任何符号与col 5 file 2中的任何同义词匹配,那么我需要将附加信息(file2中的其他列)附加到file1中的符号上,并创建一个大的输出文件
9606 '\t' 1 '\t' A1BG '\t' - '\t' A1B|ABG|GAB|HYST2477'\t' HGNC:5|MIM:138670|Ensembl:ENSG00000121410|HPRD:00726 '\t' 19 '\t' 19q13.4'\t' alpha-1-B glycoprotein '\t' protein-coding '\t' A1BG'\t' alpha-1-B glycoprotein'\t' O '\t' alpha-1B-glycoprotein '\t' 20120726
文件2是22000 KB,文件1小得多。我曾想过创建一个dict,就像有人建议的那个样,但我一直被每个文件中的不同分隔符所困扰。感谢大家迄今为止提出的问题和提供的帮助
使用
str.replace
功能
with open('file1.txt', 'r') as f1:
content1 = f1.read()
content1 = content1.replace(' /// ', '\n').split('\n')
with open('file2.txt', 'r') as f2:
content2 = f2.read()
content2 = content1.replace('|', '\n').split('\n')
然后使用列表
common_words = [i for i in content1 if i in content2]
但是,如果您已经知道每个文件中的单词都不相同,则可以使用“设置交点”来简化操作
common_words = list(set(content1) & set(content2))
然后,要将剩余部分输出到另一个文件:
common_words = [i + '\n' for i in common_words] #so that we print each word on a new line
with open('common_words.txt', 'w') as f:
f.writelines(common_words)
至于您的“附加信息”,除非您告诉我们其格式等,否则我无法帮助您。编辑
在你的评论之后,我想这就是你想要做的。我留下了下面的原始帖子,以防有任何对你有用的东西
所以,我想你应该做以下几点。首先,此代码将把file1中每个单独的同义词读入一个集合
——这是一个有用的结构,因为它将自动删除任何重复项,并且查找速度非常快。它就像一本字典,但只有键,没有值。如果您不想删除重复项,我们需要稍微更改
file1_data = set()
with open("file1.txt", "r") as fd:
for line in fd:
file1_data.update(i.strip() for i in line.split("///") if i.strip())
然后,您要运行文件2以查找匹配项:
with open("file2.txt", "r") as in_fd:
with open("output.txt", "w") as out_fd:
for line in in_fd:
items = line.split("\t")
if len(items) < 5:
# This is so we don't crash if we find a line that's too short
continue
synonyms = set(i.strip() for i in items[4].split("|"))
overlap = synonyms & file1_data
if overlap:
# Build string of columns from file2, stripping out 5th column.
output_str = "\t".join(items[:4] + items[5:])
for item in overlap:
out_fd.write("\t".join((item, output_str)))
这将创建file2\u data
作为一个字典,将一个单词映射到该行剩余项目的列表中。你也应该考虑单词是否可以重复,以及你希望如何处理,正如我在之前的评论中提到的。
在此之后,您可以读取第一个文件并将数据附加到该文件中的每个单词:
with open("file1.txt", "r") as fd:
with open("output.txt", "w") as fd_out:
for line in fd:
words = set(i.strip() for i in line.split("///"))
for file2_words, file2_cols in file2_data.iteritems():
overlap = file2_words & words
if overlap:
fd_out.write("///".join(overlap) + "\t" + "\t".join(file2_cols))
最后应该是output.txt
中的每一行,其中两个文件中的单词列表至少有一个共同单词,第一项是由//
分隔的共同单词。该输出文件中的其他列将是文件#2中匹配行中的其他列
如果这不是你想要的,你需要更具体一点
另一方面,可能有比我上面概述的O(N^2)方法更有效的方法来实现这一点(即,它在一个完整文件中运行的次数与另一个文件中的行数相同),但这需要关于如何匹配行的更详细信息
例如,您可以构造一个字典,将一个单词映射到该单词所在行的列表,这使得检查匹配行的速度比上面执行的完整扫描快得多。然而,您似乎希望行之间的重叠,这一事实稍微有点微妙,因此我认为上面概述的简单方法在没有更多细节的情况下就足够了。您的问题似乎是一个一般的编程难题。至少让我们看看你的一些想法/代码。我们将引导你正确的方式。这并不那么困难,但是你需要考虑文件1中的一个单词与文件2中的几行匹配时会发生什么事情:你追加其他列吗?以某种方式合并?就用最新发现的吗?我相信这里有很多人可以给你一些基本的提示,但是如果你想要完整的代码,还需要更多的细节。两个(小)示例文件和它们的输出将是一个开始。感谢这非常有用,我添加了一些信息,可能有助于进一步澄清我的问题,如果您有任何见解,我们将不胜感激!ThanksIt实际上看起来稍微容易一些,因为file1只包含符号,所以您可以将它们读入
集合
,以便快速查找。不过,我想我还是误解了。您是否正在尝试“筛选”文件2中与文件1中至少一个符号匹配的行?还是你总是希望每一行都能找到匹配的?问题是,若您所做的只是查找与file1的精确匹配,那个么您并没有添加任何数据,因为该sym
with open("file2.txt", "r") as in_fd:
with open("output.txt", "w") as out_fd:
for line in in_fd:
items = line.split("\t")
if len(items) < 5:
# This is so we don't crash if we find a line that's too short
continue
synonyms = set(i.strip() for i in items[4].split("|"))
overlap = synonyms & file1_data
if overlap:
# Build string of columns from file2, stripping out 5th column.
output_str = "\t".join(items[:4] + items[5:])
for item in overlap:
out_fd.write("\t".join((item, output_str)))
file2_data = {}
with open("file2.txt", "r") as fd:
for line in fd:
items = line.split("\t")
file2_data[frozenset(i.strip() for i in items[0].split("|"))] = items[1:]
with open("file1.txt", "r") as fd:
with open("output.txt", "w") as fd_out:
for line in fd:
words = set(i.strip() for i in line.split("///"))
for file2_words, file2_cols in file2_data.iteritems():
overlap = file2_words & words
if overlap:
fd_out.write("///".join(overlap) + "\t" + "\t".join(file2_cols))