Python сравнивает два массивных набора данных наиболее эффективным методом - PullRequest
1 голос
/ 23 декабря 2011

Мне нужно сравнить массивные дампы базы данных в формате xls, чтобы анализировать изменения ежедневно (брутто, верно?). В настоящее время я делаю это самым обратным способом и использую xlrd для преобразования xls в csv-файлы, а затем запускаю diff для их сравнения.

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

Мне в основном нужно найти каждое отдельное изменение, которое могло произойти в любой строке, независимо от положения этой строки в реальном дампе, и единственный реальный «поиск», о котором я мог думать, - это SKU как уникальный идентификатор (это таблица продукта из древней системы БД), но мне нужно знать намного больше, чем просто удаление или добавление продуктов, потому что они могут изменить цену или что-либо еще в этом пункте.

Должен ли я использовать наборы? И после того, как я загрузил 75+ тысяч строк этого файла базы данных в «набор», мой оперативный памяти будет истеричным?

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

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

Ответы [ 3 ]

3 голосов
/ 23 декабря 2011

Должен ли я использовать наборы?

Вероятно, нет.Однако вопрос слишком неопределенный, чтобы на него ответить.

И после того, как я загрузил 75+ тысяч строк этого файла базы данных в «набор», мое оперативное использование будет истеричным?*

Нет.75000 объектов это не много.Это не массово.Это даже не близко к массиву.

Python предлагает вам http://docs.python.org/library/difflib.html, который может помочь вам создать чуть более оптимальный алгоритм.

Поскольку вы выгружаете базу данных, лучшесоздайте дамп как файл CSV вместо файла XLS.С CSV-файлами работать намного проще.

Вот грубая сила с использованием CSV.

import csv
with open('yesterday.csv','rb') as yesterday:
    rdr= csv.DictReader( yesterday )
    baseline= {}
    for row in rdr:
        baseline[ row['key'] ]= row
with open('today.csv', 'rb' ) as today:
    rdr= csv.DictReader( today )
    update= {}
    for row in rdr:
        if baseline[row['key']] == row:
            continue
        # You have a delta             
2 голосов
/ 23 декабря 2011

Я использую наборы именно для этой цели, но стараюсь сократить количество предметов до нескольких миллионов одновременно. Как сказал С. Лотт, 75 000 - это ничто. Я использую аналогичную систему для заполнения таблиц базы данных по дате импорта, выпуская только минимальное количество INSERT и DELETE, необходимых для «исправления» таблицы по результатам последнего импорта. Основной алгоритм выглядит следующим образом:

lastset = [...]  # Populate with the output of the last run
thisset = [...]  # The current results

# Remove rows that aren't in the current result set
for row in lastset - thisset:
    deleteentry(row[0])  # Where row[0] is the unique key for the table

# Add rows that weren't in the last result set
for row in thisset - lastset:
    insertentry(row)

Чтобы убедиться, что операции над множествами бывают быстрыми и достаточно эффективными, попробуйте следующее:

>>> a = set(range(10000000))
>>> b = set(range(100, 10000100))
>>> len(a - b)
100
>>> len(b - a)
100

Это занимает около 1,25 ГБ на моем Mac. Правда, это много оперативной памяти, но, вероятно, более чем в 100 раз больше количества записей, с которыми вы работаете. Здесь операции набора выполняются намного быстрее, чем за секунду.

0 голосов
/ 23 декабря 2011

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

Ключевой вопрос, который вам может понадобиться подумать: можете ли вы как-то отсортировать данные ?

Сортированные наборы намного прощеhandle.

PS 75000 строк это не очень много.Все, что вписывается в основную память обычного компьютера, не так много.Добавьте пару нулей.

...