在二进制级别比较相同文件后,将它们分组

时间:2018-07-10 21:38:10

标签: python pandas

我有一个文件列表,需要将它们分组为相同文件的组。

例如,我有以下文件

File1
File2
File3
File4
File5
File6
File7
File8

我使用了filecmp.cmp()for循环来遍历文件列表,并进行全部比较,并将结果转储到数据帧中。然后,我对数据框进行了过滤,以获得一个子集数据框,其中仅包含在Col1和Col2中相同的文件对。例如,请参见下文。它显示File1 == File2File1 == File3等,

enter image description here
现在,我想对相同的文件进行分组。我需要添加一列“ Group”,该列显示相同文件的相同组号。第0、1、2和3行将为Group1,因为File1,File2,File3和File4相同(File2 = File4意味着File1 = File4 = File3)。第4和第5行位于Group2中。

可以在比较文件时或在创建结果数据帧之后进行分组。

我正在使用Pandas和Python。任何帮助将不胜感激。

谢谢

2 个答案:

答案 0 :(得分:0)

您可以使用图形的概念及其连接的组件来解决您的问题。您将需要模块networkx。首先,从数据框构建图形。这些文件名将是图形节点,并且如果两个文件名指向相同的文件,则两个节点之间将通过边连接:

import networkx as nx
graph = nx.from_pandas_edgelist(df, 'col1', 'col2')

现在,提取连接的组件(可以从任何节点到任何其他节点的子图):

parts = list(nx.connected_components(graph))
# [{1, 2, 3, 4, 8}, {5, 6, 7}]

如您所见,名称1,2,3,4和8指的是相同的文件,名称5,6和7也是相同的。

现在,您可能希望将零件列表转换回熊猫。用enumerate枚举零件,将它们转换为(文件名,part_id)对的列表,并从列表中创建一系列:

from itertools import chain
parts_series = pd.Series(dict(chain.from_iterable(\
                      [[(name,part_id) for name in filenames] 
                        for part_id,filenames in enumerate(parts)])))
#File1    0
#File2    0
#File3    0
#File4    0
#File5    1
#File6    1
#File7    1
#File8    0

答案 1 :(得分:0)

编写一个函数hash_of_file(),该函数返回给定文件名的文件的哈希值。然后做

file_to_hash_dict = {file_name: hash_of_file(file_name) for file_name in file_names}
hash_list = list(set(file_to_hash_dict.values()))
group_dict = {file_name:hash_list.index(file_to_hash_dict[file_name]) for file_name in file_names}