Самый эффективный (лучше, чем у меня) способ проверить, дублируется ли какое-либо изображение в какой-либо папке? - PullRequest
0 голосов
/ 29 ноября 2018

Я не уверен, правильно ли я это делаю.Я создал несколько «копий» нескольких файлов, все они должны отличаться (увеличение изображения).Теперь, потому что, возможно, шансы против меня, я хочу проверить, равен ли какой-либо из созданных файлов любому из этих созданных файлов.Либо шансы со мной, либо я плохо испортил код.Поскольку есть много файлов, я не могу проверить их вручную.Может быть, был бы более быстрый способ, чем 2 для циклов.

У меня есть следующий код.

import sys
import os
import glob
import numpy
import time
import datetime


start_time = time.time()
print(datetime.datetime.now().time())

img_dir = sys.argv[1] 
data_path = os.path.join(img_dir,'*g')
files = glob.glob(data_path)
something_went_wrong = False

for f1 in files:
    for f2 in files:
        if f1 != f2:
            if open(f1,"rb").read() == open(f2,"rb").read():
                something_went_wrong = True
                print(f1)
                print(f2)
                print("---")

print(something_went_wrong)
print("--- %s seconds ---" % (time.time() - start_time))

Ответы [ 3 ]

0 голосов
/ 29 ноября 2018

В этом подходе используется функция хеширования в сочетании со словарем списка файлов со счетчиком количества раз, которое появляется каждый элемент - небольшое расширение в другом подходе.

Предположительно, вы говорите о дубликатеимена файлов в разных папках, что означало бы, что я бы поставил начальные file_list вместе немного по-другому, но это основа того, как бы я решил эту проблему (в зависимости от того, что возвращает glob.glob)

import hashlib


file_list = []

def test_hash(filename_to_test1, filename_to_test2):
    """
    """
    filename_seq = filename_to_test1, filename_to_test2
    output = []
    for fname in filename_seq:
        with open(fname, "rb") as opened_file:
            file_data = opened_file.readlines()
            file_data_as_string = b"".join(file_data)
            _hash = hashlib.sha256()
            _hash.update(file_data_as_string)
            output.append(_hash.hexdigest())
    if output[0] == output[1]:
        print "File match"
    else:
        print "Mismatch between file and reference value"

possible_duplicates = {}
for idx, fname in enumerate(file_list):
    if fname in possible_duplicates:
        possible_duplicates[fname].append(idx)
    elif fname not in possible_duplicates:
        possible_duplicates[fname] = [idx]

for fname in possible_duplicates:
    if len(possible_duplicates[fname]) > 1:
        for idx, list_item in enumerate(possible_duplicates[fname]):
            test_hash(possible_duplicates[fname][0], possible_duplicates[fname][idx])
0 голосов
/ 29 ноября 2018

Как сказано в комментариях, время группировки по размеру экономит:

import os
from collections import defaultdict
def fin_dup(dir):
    files=defaultdict(set)
    res=[]
    for fn in os.listdir(dir):
        if os.path.isfile(fn):
            files[os.stat(fn).st_size].add(fn) # groups files by size

    for size,s in sorted(files.items(),key=lambda x : x[0],reverse=True): #big first 
        while s:
            fn0=s.pop()
            s0={fn0}
            for fn in s:
                if open(fn0,'rb').read() == open(fn,'rb').read(): s0.add(fn)
            s -= s0
            if len(s0) > 1: res.append(s0)
    return res

Эта функция занимает менее 1 секунды для сканирования каталога с 1000 файлами и поиска 79 дубликатов.Простое хеширование файлов стоит 10 секунд.

0 голосов
/ 29 ноября 2018

Просто попробуйте использовать хеш, как предложено.Если один пиксель изменился, хэш также изменится.

import hashlib
def hash_file(filename):
   # use sha1 or sha256 or other hashing algorithm
   h = hashlib.sha1()

   # open file and read it in chunked
   with open(filename,'rb') as file:
       chunk = 0
       while chunk != b'':
           chunk = file.read(1024)
           h.update(chunk)

   # return string
   return h.hexdigest()

https://www.pythoncentral.io/hashing-files-with-python/

Это не зависит от имени файла или метаданных!Поместите результаты в массив данных, чтобы их можно было легко получить.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...