Найдите повторяющиеся строки и файл, содержащий дублированную строку, в большом фрейме данных, разбитом на несколько файлов

#python #pandas #dataframe #bigdata

#питон #pandas #фрейм данных #bigdata

Вопрос:

Итак, у меня есть большой фрейм данных, разделенный на 404 файла Excel. Фрейм данных в виде столбца ID, и я должен:

  1. Найдите, есть ли повторяющиеся строки
  2. В случае повторяющейся строки выведите два файла, содержащих дублированную строку

Например, предположим, что строка с идентификатором ключа «ID_101» содержится в файлах # 10 и # 209. Скрипт должен вывести «Повторяющаяся строка: ID_101 содержится как в файле # 10, так и в файле # 209».

Я попробовал этот подход: создал набор со всеми идентификаторами ключей и словарь, который сопоставляет каждый идентификатор с файлом. Когда я перебираю файлы и их строки

  1. Если идентификатор есть в наборе, он выполнит поиск по словарю и выведет, где эта строка уже была найдена.
  2. Если вместо этого идентификатор отсутствует в наборе, он добавит его в набор и создаст новую запись в словаре, которая сопоставит этот идентификатор с текущим файлом

Таким образом, MWE будет:

 import os, sys, pandas

ids_set = set()
ids_map = dict()

for root, dirs, files in os.walk(sys.argv[1]):
    for file in files:
        in_file = pandas.read_excel(os.path.join(root, file), header=0, sheet_name="Results")    

        # Check for duplicated companies
        this_ids = list(in_file['BvD ID number'])
        for this_id in this_ids:
            if this_id in ids_set:
                print("ERROR: duplicate ID '{}', already found in '{}'".format(this_id, ids_map[this_id]))
            else:
                ids_set.add(this_id)
                ids_map[this_id] = filen
 

Проблема в том, что в 300-м с чем-то файле я получаю ошибку памяти при попытке получить доступ к словарю, предположительно потому, что он стал слишком большим.

Как я могу достичь своей цели с помощью такого большого фрейма данных?

Комментарии:

1. Вы пытаетесь найти дубликаты только в файлах или в файлах, которые также учитываются? Другое дело, что вы можете удалить ids_set и вместо этого проверить if this_id in ids_map .

2. @QuangHoang те, что находятся внутри файлов, также учитываются. Быстрее ли искать в наборе, чем в словаре?

3. Я считаю, что это то же самое. Кроме того, вам не нужно создавать this_ids . Вы можете пройти через саму колонну.

Ответ №1:

Вы получаете ошибку памяти, потому что вы делаете это рекурсивно, в то время как Pandas оптимизирован для векторизованной работы.

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

Что — то вроде:

 df = pandas.DataFrame()

for root, dirs, files in os.walk(sys.argv[1]):
    for file in files:
        current_df = pandas.read_excel(filen, header=0, sheet_name="Results")
        current_df["source_file"] = root   file

        df = df.append(current_file, ignore_index=True)

 

А затем, чтобы получить дублированные строки:

 duplicated_df = df[df.duplicated(subset="ID", keep=False)]
print(duplicated_df)
 

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

Комментарии:

1. он ничего не делает recursively , скорее serially . Во всяком случае, его код требует меньше памяти, чем ваш, поскольку он обрабатывает один фрейм данных за раз, а не 401.

2. @ggrelet Спасибо, я пробовал это, но я не могу прочитать объединенный фрейм данных в памяти. Я получаю либо ошибку памяти с low_memory=True помощью и pandas.errors.ParserError: Error tokenizing data. C error: out of memory с low_memory=False