【问题标题】:Group identical files after comparing them at the binary level在二进制级别比较它们后对相同的文件进行分组
【发布时间】:2018-07-10 21:38:09
【问题描述】:

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

例如,我有如下文件

File1
File2
File3
File4
File5
File6
File7
File8

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


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

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

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

谢谢

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    您可以使用图形及其连接组件的概念来解决您的问题。您将需要模块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 也是如此。

    现在,您可能希望将部件列表转换回 pandas。枚举带有enumerate 的部分,将它们转换为 (filename,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
    

    【讨论】:

    • 这些组不仅仅是连接的组件,而是等价类。也就是说,一个组件的每个成员都具有该组件的每个其他成员的边缘。构建一个完整的图表是多余的;如果有 n 个边和 k 个分量,当任务可以在 O(nk) 内完成时,你的算法是 O(n^2)。
    • @Accumulation 是的,它们是等价类。是的,有更有效的方法来解决问题。我并不声称我的解决方案是最优的。然而,我声称它是正确的。
    • 绝妙的答案!我什至从未想过使用 networkx 来解决这个问题!
    【解决方案2】:

    编写一个函数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}
    

    【讨论】:

      猜你喜欢
      • 2012-08-20
      • 1970-01-01
      • 2014-05-22
      • 2013-11-28
      • 2016-03-17
      • 1970-01-01
      • 2011-06-14
      • 2011-12-10
      • 1970-01-01
      相关资源
      最近更新 更多