Як опрацювати CSV файл з 6 млн рядків?
Підписуйтеся на Telegram-канал «DOU #tech», щоб не пропустити нові технічні статті
Є CSV файл в якому щось близько 6583257 рядків з описом певних товарів. Потрібно по двом критеріям знайти товари. Ці критерії це артикул і виробник. Потім серед груп товарів які мають однаковий артикул і виробника знайти товар з найменшою ціною а всі інші з цього набору однакових товарів видалити. Те що вийшло записати в CSV. Файл розміром більше 400 мебібайт. Що я придумав: групувати номера рядків по виробникам і артикулам і виходить два обєкта (один для виброників інший для артикулів) в яких містяться словники з назвами виробників або артикулів в якості ключа а в цих словниках є масив numbers з номерами рядків які містять товар з вказаним виробником або артикулом.
articles = {} { # Всі рядки в яких є виробник prod1 'prod1': {'numbers': [1,2,38555, 387]} 'prod2': {'numbers': [33,22,355, 1000]} }
Після збору даних даних ось що роблю: масив numbers кожного виробника порівняти з масивом numbers всіх артикулів і якщо перетин масивів містить більше одного елементу, додати цей масив номерів рядків до масиву з копіями. Використовую Пітонівську функцію intersection. Проблема в тому що програма виконується дуже довго і я так і не дочекався закінчення її роботи тому що час очікування наблизився до 5 годин. Скрипт в оперативці розрісся майже на 800 мебібайт. Ось шматок коду:
for brand in list(brands.keys()): # articles обєкт з артикулями result = find_duplicates(brands[brand]['numbers'], articles) if result: # id потрібне для групування номерів рядків id = hash(brand) + hash(result['article']) duplicates[id] = {'row_numbers': result['row_numbers']} def find_duplicates(number_list, articles): result = {} for article, numbers in articles.items(): for k2, number_array in numbers.items(): matches = set(number_list).intersection(number_array) if len(matches) > 1: result['row_numbers'] = matches result['article'] = article return result
Найкращі коментарі пропустити