Загрузка из pkl - согласен, не быстрая (грузить приходится все данные). А вот у SQLite реализована очень эффективное чтение файла БД по указателям и индексу (частичное чтение). Хотя у себя на Pi4 вижу вдвое более высокую скорость чтения (13 и 7 секунд), возможно из-за более быстрой MicroSD. Также использую разгон CPU до 2 ГГц (Raspberrry OS 64).
Но поиск (выборка) у SQLite c индексами в вашем опыте - самое лучшее 83 миллисекунды, а у Pandas на Pi4 у меня 0.5-2 миллисекунды. Разница в 40 раз и она достаточна для того чтобы признать Pandas самым быстрым решением из рассмотренных, а возможно и из существующих (особенно если нужно найти несколько кодов).
Для чистоты эксперимента можно проверить еще и IN-MEMORY базы данных SQLite, но уверен что результат будет не лучше чем у Pandas, хотя наверняка приблизится к ней вплотную.
Ну раз уж SQLite помогли индексом, то будет честно и Pandas помочь (им же). Для роста скорости загрузки данных и выборки можно сделать это:
1) Избавиться от типов object (например, преобразовать их в string): df.Name.astype('string'). Это же избавит от ошибок при сортировке, сравнении итд по Name
2) То что ищем - нужно сделать индексом: df.set_index('UPCEAN', inplace=True)
3) Обязательно его отсортировать: df.sort_index(inplace=True)
4) Сохранить df в бинарный pickle-формат Python с простым сжатием (zip): df.to_pickle('uhtt_barcode_ref_all.pkl', compression='zip') Сжатие замедлит чтение в ~2 раза, но здорово помогает при скачивании данных по LAN или из Интернет (для Raspberry Pi4 c медленной MicroSD м.б. актуально)
5) При выборке нескольких столбцов по индексу - быстрее всего сработает локатор loc[], а не методы query() или at(). Локатор, кстати, позволяет и изменять исходные данные, не только читать.
В результате по сравнению с итогами поста - имеем ~10-кратное ускорение первичного чтения и ~500-кратное для выборки, и все это - только средствами Python/Pandas. Метрики:
%%time import pandas as pd df = pd.read_pickle('uhtt_barcode_ref_all.pkl', compression='zip') # загрузили чистый датасет Wall time: 5.74 s # было ~1 минута
%%timeit df.loc[4603726031011, ['Name','CategoryName','BrandName']].to_frame() # выбрали записи 581 µs ± 21.2 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) # было 0,3 секунды
Отказ от сжатия "консервы" (pkl-файла) или использование pyarrow выведет Pandas в бесспорные победители, но SQLite, безусловно, прекрасна и является самой быстрой SQL БД. К тому же она прекрасно поддерживается в языке Python "из коробки" (стандартная библиотека) и Pandas умеет с ней работать.
Загрузка из pkl - согласен, не быстрая (грузить приходится все данные). А вот у SQLite реализована очень эффективное чтение файла БД по указателям и индексу (частичное чтение). Хотя у себя на Pi4 вижу вдвое более высокую скорость чтения (13 и 7 секунд), возможно из-за более быстрой MicroSD. Также использую разгон CPU до 2 ГГц (Raspberrry OS 64).
Но поиск (выборка) у SQLite c индексами в вашем опыте - самое лучшее 83 миллисекунды, а у Pandas на Pi4 у меня 0.5-2 миллисекунды. Разница в 40 раз и она достаточна для того чтобы признать Pandas самым быстрым решением из рассмотренных, а возможно и из существующих (особенно если нужно найти несколько кодов).
Для чистоты эксперимента можно проверить еще и IN-MEMORY базы данных SQLite, но уверен что результат будет не лучше чем у Pandas, хотя наверняка приблизится к ней вплотную.
Ну раз уж SQLite помогли индексом, то будет честно и Pandas помочь (им же). Для роста скорости загрузки данных и выборки можно сделать это:
1) Избавиться от типов object (например, преобразовать их в string): df.Name.astype('string'). Это же избавит от ошибок при сортировке, сравнении итд по Name
2) То что ищем - нужно сделать индексом: df.set_index('UPCEAN', inplace=True)
3) Обязательно его отсортировать: df.sort_index(inplace=True)
4) Сохранить df в бинарный pickle-формат Python с простым сжатием (zip): df.to_pickle('uhtt_barcode_ref_all.pkl', compression='zip') Сжатие замедлит чтение в ~2 раза, но здорово помогает при скачивании данных по LAN или из Интернет (для Raspberry Pi4 c медленной MicroSD м.б. актуально)
5) При выборке нескольких столбцов по индексу - быстрее всего сработает локатор loc[], а не методы query() или at(). Локатор, кстати, позволяет и изменять исходные данные, не только читать.
В результате по сравнению с итогами поста - имеем ~10-кратное ускорение первичного чтения и ~500-кратное для выборки, и все это - только средствами Python/Pandas. Метрики:
%%time
import pandas as pd
df = pd.read_pickle('uhtt_barcode_ref_all.pkl', compression='zip') # загрузили чистый датасет
Wall time: 5.74 s # было ~1 минута
%%timeit
df.loc[4603726031011, ['Name','CategoryName','BrandName']].to_frame() # выбрали записи
581 µs ± 21.2 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) # было 0,3 секунды
Отказ от сжатия "консервы" (pkl-файла) или использование pyarrow выведет Pandas в бесспорные победители, но SQLite, безусловно, прекрасна и является самой быстрой SQL БД. К тому же она прекрасно поддерживается в языке Python "из коробки" (стандартная библиотека) и Pandas умеет с ней работать.