Работа с большими объемами данных в Python
Сам вопрос: существует ли способ работы с большими объемами данных в питоне, если количество оперируемых строк примерно 1-1,5 миллиарда, а объем ОЗУ ограничен 16ГБ? Структура данных следующая: список кортежей, которые всегда состоят из двух элементов, первый из которых строка, второй - число. Данные выгружаются из БД. Пример структуры:
[
('hgasuhga', 1546873),
('dhfgusure', 68874840),
...
('jaghusglkjasd', 1565748)
]
Мне необходимо сгруппировать эти данные в defaultdict, ключом которого будет число, а значением - строка. Соответственно, получится следующая структура:
{
545158: ['dsh','sryhgesrt','srytg','rstg'],
5645847568: ['tsst','aers'],
...
698: ['adstg','datss','dtsa']
}
Я могу выгружать данные в список (так примерно раза в 3 быстрее) или сразу в словарь. Мои 16 Гб ОЗУ заканчиваются примерно на 140 миллионах записей, если я использую список, и на 176 миллионах записей, если сразу выгружать в словарь. Рассматривал вариант выгружать данные итерационно, а не все сразу, но тогда группировка не отработает корректно, а будет действовать в пределах выгружаемой итерации (поправьте, пожалуйста, если ошибаюсь).
Ответы (1 шт):
Для решения я бы рассмотрел 2 пути:
- ClickHouse side
ClickHouse может заранее просчитывать агрегаты - см AggregatingMergeTree - таким образом, он сам будет производить все вычисления, а получение искомого результата будет очень быстрым.
- App side
Использование потокового API и обработка данных поблоково с использованием clickhouse_driver.
from clickhouse_driver import Client
client = Client(host='localhost')
settings = {'max_block_size': 1_000_000}
rows_gen = client.execute_iter(
# just emulate origin dataset
'SELECT toString(number % 4096) AS key, number % 1024 AS value '
'FROM system.numbers '
'LIMIT 1000111222', settings=settings)
result = {}
for row in rows_gen:
if row[1] not in result:
result[row[1]] = []
result[row[1]].append(row[0])
print(result)
requirements.txt
clickhouse_driver