Вы можете использовать collections.Counter
для подсчета количества вхождений.
f = open('text.csv')
csv_f = csv.reader(f)
next(csv_f, None) # Ignore header row
c = collections.Counter((year, product) for year, product, country in csv_f)
print(c)
# Output: Counter({('2018', 'food'): 2, ('2018', 'drink'): 1, ('2019', 'food'): 1, ('2019', 'car'): 1})
Чтобы записать его обратно в файл CSV, вы можете использовать .items()
и составить список для превратите его обратно в плоский список и напишите, используя writerows
.
with open('output.csv', 'w') as csvfile:
writer = csv.writer(csvfile)
writer.writerow(('year', 'product', 'product_sum'))
writer.writerows([(key[0], key[1], value) for key, value in c.items()])
Примечание. Для Python 2 используйте iteritems()
вместо items()
.
Вы можете использовать reduce
для этой проблемы, но лично я не нахожу это ни естественным, ни очень Pythoni c. Но вот как это делается в любом случае.
def reduce_func(acc, update):
year, product, country = update
acc[(year, product)] += 1
return acc
resultdict = reduce(reduce_func,
csv_f,
collections.defaultdict(lambda: 0))
print(resultdict)
# Output: defaultdict(<function <lambda> at 0x1007042f0>, {('2018', 'food'): 2, ('2018', 'drink'): 1, ('2019', 'food'): 1, ('2019', 'car'): 1})
Если вы не хотите / не можете использовать collections.Counter
по какой-то причине, я бы порекомендовал go с ответом Amal TS ', чтобы построить словарь в al oop вместо.