Анализ файла с разделителями-запятыми с помощью Python и добавление полей валюты
Я пытаюсь использовать Python для анализа файла с разделителями-запятыми с макетом, похожим на это:
AccountNumber,Invoice_Number,Gross_Amt,Adjustments,TotalDue
"234","56787","19.37",,"19.37"
"234","56788","204.76","-10.00","194.76"
"234","56789","139.77",,"139.77"
"567","12543","44.89","30.00","74.89"
Чего я хочу добиться, так это суммировать общую сумму, корректировки и итоговую задолженность, а затем добавить их в конец каждой строки (или только в последнюю строку каждого документа).
У меня вопрос, как я могу создать переменную, которая добавляет поля только при условии, что номер счета совпадает? Например, на английском я бы сказал:
Проверьте номер счета: добавьте Gross_amt в каждой строке, в то время как номер счета равен номеру счета в предыдущей строке, затем, когда номер счета изменяется, добавьте сумму полей gross_amt в качестве нового поля в конце последней строки для этого счета как Gross_Amt_Total, Начать сначала.
3 ответа
Вы могли бы использовать itertools.groupby()
:
import csv
from itertools import groupby
from operator import itemgetter
with open("data.csv", "rb") as f:
next(f) # Skip header
for account, lines in groupby(csv.reader(f), itemgetter(0)):
gross_amount = 0.
for line in lines:
print line
gross_amount += float(line[2])
print "The total gross amount for account", account, "is", gross_amount
Модуль CSV для чтения данных и itertools.groupby для группировки по номеру счета:
import csv
from itertools import groupby
from StringIO import StringIO
data = StringIO('''\
AccountNumber,Invoice_Number,Gross_Amt,Adjustments,TotalDue
"234","56787","19.37",,"19.37"
"234","56788","204.76","-10.00","194.76"
"234","56789","139.77",,"139.77"
"567","12543","44.89","30.00","74.89"
''')
# Grab the header and rows of the data.
# groupby requires data sorted on the groupby key.
reader = csv.reader(data)
header = next(reader)
rows = sorted(reader)
print '{:13} {:14} {:9} {:11} {:8}'.format(*header)
# group by first item (acct number)
for acct,grp in groupby(rows,lambda r: r[0]):
print
gross_amt_total = 0
adjustments_total = 0
total_due_total = 0
for item in grp:
# everything comes in as a string, and blank strings don't cvt to float.
gross = float(item[2]) if item[2] else 0.0
adj = float(item[3]) if item[3] else 0.0
due = float(item[4]) if item[4] else 0.0
print '{:13} {:14} {:9.2f} {:11.2f} {:8.2f}'.format(item[0],item[1],gross,adj,due)
gross_amt_total += gross
adjustments_total += adj
total_due_total += due
print
print 'Totals for #{:13} {:9.2f} {:11.2f} {:8.2f}'.format(
acct,gross_amt_total,adjustments_total,total_due_total)
Выход
AccountNumber Invoice_Number Gross_Amt Adjustments TotalDue
234 56787 19.37 0.00 19.37
234 56788 204.76 -10.00 194.76
234 56789 139.77 0.00 139.77
Totals for #234 363.90 -10.00 353.90
567 12543 44.89 30.00 74.89
Totals for #567 44.89 30.00 74.89
Смотрите здесь, как читать CSV. http://docs.python.org/library/csv.html По сути, вы хотите сохранить словарь, который сопоставляет учетную запись со значением, которое вы хотите получить. Для каждой записи в файле вы индексируете dict номером счета и добавляете только что прочитанное значение с тем, что уже есть в dict.