#python #pandas #dataframe #bigdata
#питон #pandas #фрейм данных #bigdata
Вопрос:
Итак, у меня есть большой фрейм данных, разделенный на 404 файла Excel. Фрейм данных в виде столбца ID, и я должен:
- Найдите, есть ли повторяющиеся строки
- В случае повторяющейся строки выведите два файла, содержащих дублированную строку
Например, предположим, что строка с идентификатором ключа «ID_101» содержится в файлах # 10 и # 209. Скрипт должен вывести «Повторяющаяся строка: ID_101 содержится как в файле # 10, так и в файле # 209».
Я попробовал этот подход: создал набор со всеми идентификаторами ключей и словарь, который сопоставляет каждый идентификатор с файлом. Когда я перебираю файлы и их строки
- Если идентификатор есть в наборе, он выполнит поиск по словарю и выведет, где эта строка уже была найдена.
- Если вместо этого идентификатор отсутствует в наборе, он добавит его в набор и создаст новую запись в словаре, которая сопоставит этот идентификатор с текущим файлом
Таким образом, 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