Файл 80 Гб - Создание фрейма данных, который представляет данные на основе списка округов - PullRequest
0 голосов
/ 06 октября 2019

Я работаю с набором данных 80 Гб в Python. Данные имеют 30 столбцов и ~ 180 000 000 строк.

Я использую параметр размера чанка в pd.read_csv для чтения данных в чанках, где затем перебираю данные, чтобы создать словарь округов с соответствующей частотой.

Этогде я застрял. Получив список округов, я хочу построчно перебирать куски по строкам, суммируя значения 2–3 других столбцов, связанных с каждым округом, и помещая их в новый DataFrame. Это примерно 4 столбца и 3000 строк, что более удобно для моего компьютера.

Я действительно не знаю, как это сделать, я впервые работаю с большим набором данных в python.

import pandas as pd
from collections import defaultdict

df_chunk = pd.read_csv('file.tsv', sep='\t', chunksize=8000000)
county_dict = defaultdict(int)

for chunk in df_chunk:
    for county in chunk['COUNTY']:
        county_dict[county] += 1

for chunk in df_chunk:
    for row in chunk:
    # I don't know where to go from here

Я ожидаю, что смогу создать DataFrame со столбцом всех округов, столбцом для общих продаж продукта "1" в округе, другим столбцом для продаж продукта в округе, а затембольше столбцов столько же, сколько необходимо.

1 Ответ

0 голосов
/ 06 октября 2019

Идея

Я не был уверен, есть ли у вас данные для разных округов (например, в Великобритании или США) или стран (в мире), поэтомуЯ решил получить данные, касающиеся стран .

Идея состоит в том, чтобы:

  • Группировать данные из каждого чанка по стране.
  • Создатьчастичный результат для этого блока, как DataFrame с:
    • Суммы каждого столбца интереса (по стране).
    • Количество строк в стране.
  • Чтобы выполнить конкатенацию частичных результатов (через мгновение), каждый частичный результат должен содержать номер чанка в качестве дополнительного уровня индекса.
  • Конкатенация частичных результатов по вертикали (из-за дополнительныхуровень индекса, каждая строка имеет свой индекс).
  • Конечный результат (общая сумма и количество строк) может быть вычислен как сумма вышеуказанного результата, сгруппированная по стране (исключая номер чанка).

Тестовые данные

Исходный файл CSV содержит country имена и 2 столбца для суммирования ( Tab разделены):

Country Amount_1    Amount_2
Austria 41  46
Belgium 30  50
Austria 45  44
Denmark 31  42
Finland 42  32
Austria 10  12
France  74  54
Germany 81  65
France  40  20
Italy   54  42
France  51  16
Norway  14  33
Italy   12  33
France  21  30

Для целей теста я принял размер куска всего 5 строк:

chunksize = 5

Решение

Основной цикл обработки (и подготовительные этапы) следующие:

df_chunk = pd.read_csv('Input.csv', sep='\t', chunksize=chunksize)
chunkPartRes = []   # Partial results from each chunk
chunkNo = 0
for chunk in df_chunk:
    chunkNo += 1
    gr = chunk.groupby('Country')
    # Sum the desired columns and size of each group
    res = gr.agg(Amount_1=('Amount_1', sum), Amount_2=('Amount_2', sum))\
        .join(gr.size().rename('Count'))
    # Add top index level (chunk No), then append
    chunkPartRes.append(pd.concat([res], keys=[chunkNo], names=['ChunkNo']))

Чтобы объединить вышеуказанные частичные результаты в один DataFrame , но по-прежнему с отдельными результатами для каждого чанка, запустите:

chunkRes = pd.concat(chunkPartRes)

Для моих тестовых данных результат будет:

                 Amount_1  Amount_2  Count
ChunkNo Country                           
1       Austria        86        90      2
        Belgium        30        50      1
        Denmark        31        42      1
        Finland        42        32      1
2       Austria        10        12      1
        France        114        74      2
        Germany        81        65      1
        Italy          54        42      1
3       France         72        46      2
        Italy          12        33      1
        Norway         14        33      1

И для генерации окончательного результата, суммируя данные из всехкуски, но с разделением по странам, запустите:

res = chunkRes.groupby(level=1).sum()

Результат:

         Amount_1  Amount_2  Count
Country                           
Austria        96       102      3
Belgium        30        50      1
Denmark        31        42      1
Finland        42        32      1
France        186       120      4
Germany        81        65      1
Italy          66        75      2
Norway         14        33      1

Суммируя

Даже если мы посмотрим только на то, как числавычисляется число строк для каждой страны, это решение более «пандасонское» и элегантное, чем использование defaultdict и увеличение в цикле обработки каждой строки.

Группировка и подсчет строк по группе работает значительнобыстрее, чем цикл, работающий со строками.

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