Идея
Я не был уверен, есть ли у вас данные для разных округов (например, в Великобритании или США) или стран (в мире), поэтомуЯ решил получить данные, касающиеся стран .
Идея состоит в том, чтобы:
- Группировать данные из каждого чанка по стране.
- Создатьчастичный результат для этого блока, как 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 и увеличение в цикле обработки каждой строки.
Группировка и подсчет строк по группе работает значительнобыстрее, чем цикл, работающий со строками.