发现相似文件中的不同行
Discover different lines across similar files
我有一个包含数万个短句的文本文件:
go to venice
come back from grece
new york here i come
from belgium to russia and back to spain
我运行一个标记算法产生这个句子文件的标记输出:
go to <place>venice</place>
come back from <place>grece</place>
<place>new york</place> here i come
from <place>belgium</place> to <place>russia</place> and back to <place>spain</place>
算法 运行 对输入进行多次处理,每次都产生略有不同的标记。我的目标是确定那些出现差异的行。换句话说,打印 N 个结果文件中标记不同的所有话语。
例如N=10,我得到10个标记文件。假设所有 10 个标记文件的第 1 行始终标记相同 - 不要打印它。假设第 2 行以这种方式标记一次,以其他方式标记 9 次 - 打印它。等等。
对于N=2很简单,我只是运行 diff。但是如果我有 N=10 个结果怎么办?
如果将它们全部与第一个文本进行比较,那么您可以获得所有不同文本的列表。这可能不是最快的方法,但它会起作用。
import difflib
n1 = '1 2 3 4 5 6'
n2 = '1 2 3 4 5 6'
n3 = '1 2 4 5 6 7'
l = [n1, n2, n3]
m = [x for x in l if x != l[0]]
diff = difflib.unified_diff(l[0], l.index(m))
print ''.join(diff)
如果您有标记的文件 - 只需为每一行创建一个计数器,记录您看到它的次数:
# use defaultdict for convenience
from collections import defaultdict
# start counting at 0
counter_dict = defaultdict(lambda: 0)
tagged_file_names = ['tagged1.txt', 'tagged2.txt', ...]
# add all lines of each file to dict
for file_name in tagged_file_names:
with open(file_name) as f:
# use enumerate to maintain order
# produces (LINE_NUMBER, LINE CONTENT) tuples (hashable)
for line_with_number in enumerate(f.readlines()):
counter_dict[line_with_number] += 1
# print all values that do not repeat in all files (in same location)
for key, value in counter_dict.iteritems():
if value < len(tagged_file_names):
print "line number %d: [%s] only repeated %d times" % (
key[0], key[1].strip(), value
)
演练:
首先,我们创建一个数据结构,使我们能够计算我们的条目,这些条目是编号的行。此数据结构是一个 collections.defaultdict
,默认值为 0
- 这是新添加行的计数(每次添加增加到 1)。
然后,我们使用 tuple
创建实际条目,它是 可散列的 ,因此它可以用作字典键,默认情况下 与其他元组具有深度可比性。这意味着 (1, "lolz")
等于 (1, "lolz")
但不同于 (1, "not lolz")
或 (2, lolz)
- 所以它适合我们使用深度比较线来解释内容和位置。
现在剩下要做的就是使用简单的 for
循环添加所有条目,然后查看所有文件中出现的键(对应于编号行)(即 - 它们的值等于数字提供的标记文件)。
示例:
reut@tHP-EliteBook-8470p:~/python/counter$ cat tagged1.txt
123
abc
def
reut@tHP-EliteBook-8470p:~/python/counter$ cat tagged2.txt
123
def
def
reut@tHP-EliteBook-8470p:~/python/counter$ ./difference_counter.py
line number 1: [abc] only repeated 1 times
line number 1: [def] only repeated 1 times
我有一个包含数万个短句的文本文件:
go to venice
come back from grece
new york here i come
from belgium to russia and back to spain
我运行一个标记算法产生这个句子文件的标记输出:
go to <place>venice</place>
come back from <place>grece</place>
<place>new york</place> here i come
from <place>belgium</place> to <place>russia</place> and back to <place>spain</place>
算法 运行 对输入进行多次处理,每次都产生略有不同的标记。我的目标是确定那些出现差异的行。换句话说,打印 N 个结果文件中标记不同的所有话语。
例如N=10,我得到10个标记文件。假设所有 10 个标记文件的第 1 行始终标记相同 - 不要打印它。假设第 2 行以这种方式标记一次,以其他方式标记 9 次 - 打印它。等等。
对于N=2很简单,我只是运行 diff。但是如果我有 N=10 个结果怎么办?
如果将它们全部与第一个文本进行比较,那么您可以获得所有不同文本的列表。这可能不是最快的方法,但它会起作用。
import difflib
n1 = '1 2 3 4 5 6'
n2 = '1 2 3 4 5 6'
n3 = '1 2 4 5 6 7'
l = [n1, n2, n3]
m = [x for x in l if x != l[0]]
diff = difflib.unified_diff(l[0], l.index(m))
print ''.join(diff)
如果您有标记的文件 - 只需为每一行创建一个计数器,记录您看到它的次数:
# use defaultdict for convenience
from collections import defaultdict
# start counting at 0
counter_dict = defaultdict(lambda: 0)
tagged_file_names = ['tagged1.txt', 'tagged2.txt', ...]
# add all lines of each file to dict
for file_name in tagged_file_names:
with open(file_name) as f:
# use enumerate to maintain order
# produces (LINE_NUMBER, LINE CONTENT) tuples (hashable)
for line_with_number in enumerate(f.readlines()):
counter_dict[line_with_number] += 1
# print all values that do not repeat in all files (in same location)
for key, value in counter_dict.iteritems():
if value < len(tagged_file_names):
print "line number %d: [%s] only repeated %d times" % (
key[0], key[1].strip(), value
)
演练:
首先,我们创建一个数据结构,使我们能够计算我们的条目,这些条目是编号的行。此数据结构是一个 collections.defaultdict
,默认值为 0
- 这是新添加行的计数(每次添加增加到 1)。
然后,我们使用 tuple
创建实际条目,它是 可散列的 ,因此它可以用作字典键,默认情况下 与其他元组具有深度可比性。这意味着 (1, "lolz")
等于 (1, "lolz")
但不同于 (1, "not lolz")
或 (2, lolz)
- 所以它适合我们使用深度比较线来解释内容和位置。
现在剩下要做的就是使用简单的 for
循环添加所有条目,然后查看所有文件中出现的键(对应于编号行)(即 - 它们的值等于数字提供的标记文件)。
示例:
reut@tHP-EliteBook-8470p:~/python/counter$ cat tagged1.txt
123
abc
def
reut@tHP-EliteBook-8470p:~/python/counter$ cat tagged2.txt
123
def
def
reut@tHP-EliteBook-8470p:~/python/counter$ ./difference_counter.py
line number 1: [abc] only repeated 1 times
line number 1: [def] only repeated 1 times