Если файл не отсортирован, его трудно обработать без использования большого количества памяти: вам нужно поддерживать непрерывную агрегацию для каждого ключа (списка значений измерений), который появляется в файле.Возможно, есть хороший способ сделать это, но это зависит от деталей, таких как, сколько возможностей.Может быть возможно выполнить обработку порциями, а затем обработать порции вместе, но вам все еще понадобится достаточно памяти для хранения всех текущих значений ключей, с которыми производится агрегирование.
Простое и довольно общее решениесортировать первым.Команда unix sort
удачно отсортирует файлы, которые слишком велики, чтобы уместиться в память.Затем отсортированный файл может быть легко обработан кусками.Вот последовательность, которая показывает принцип: вам может потребоваться изменить некоторые детали:
Сначала я немного расширил ваш файл, чтобы показать, что происходит, и удалил строку заголовка (которая sort
будет восприниматься как данные).:
input_file.csv:
foo bar 1 1
a a 9 9 9
z z 8 8 8
a a 9 9 9
foo bar 2 2
foo bar 1 4 2
foo bar foobar 2 1
z z 7 7 7
a a 9 9 9
Затем я использовал команду:
sort input_file.csv -o input_file_sorted.csv --key=1,3
Это дало мне:
input_file_sorted.csv
a a 9 9 9
a a 9 9 9
a a 9 9 9
foo bar 1 4 2
foo bar 1 1
foo bar 2 2
foo bar foobar 2 1
z z 7 7 7
z z 8 8 8
Затем я запустил эту программу на Python:
import csv
number_of_dims = 3
number_of_aggs = 3
def aggregate(agg, data):
for i,d in enumerate(data):
if d != "":
agg[i] += int(d)
return
with open("input_file_sorted.csv", newline="") as f1:
with open("output_file,csv", "w", newline="") as f2:
csv_reader = csv.reader(f1, delimiter='\t')
csv_writer = csv.writer(f2, delimiter='\t')
key = None
agg = [0] * number_of_aggs
for l in csv_reader:
new_key = l[:number_of_dims]
if key is None:
key = new_key
if key != new_key:
csv_writer.writerow(key + agg)
agg = [0] * number_of_aggs
key = new_key
aggregate(agg, l[number_of_dims:])
csv_writer.writerow(key + agg)
и это меня достало:
output_file.csv:
a a 27 27 27
foo bar 1 4 2
foo bar 3 1 2
foo bar foobar 0 2 1
z z 15 15 15
Надеюсь, это поможет!