我在csv中有需要解析的数据。它看起来像:
Date, Name, Subject, SId, Mark
2/2/2013, Andy Cole, History, 216351, 98
2/2/2013, Andy Cole, Maths, 216351, 87
2/2/2013, Andy Cole, Science, 217387, 21
2/2/2013, Bryan Carr, Maths, 216757, 89
2/2/2013, Carl Jon, Botany, 218382, 78
2/2/2013, Bryan Carr, Biology, 216757, 27
我需要将Sid作为键,并使用此键汇总标记列中的所有值。 输出将类似于:
Sid Mark
216351 185
217387 21
216757 116
218382 78
我不必在文件上写输出。我执行python文件时只需要它。 这是一个类似的question。 应如何更改以跳过其间的列?
答案 0 :(得分:2)
这是直方图的概念。使用defaultdict(int)
中的collections
并遍历您的行。使用'Sid'值作为dict的键,并将'Mark'值添加到当前值。
int类型的defaultdict确保如果某个键到目前为止不存在,则其值将初始化为0。
from collections import defaultdict
d = defaultdict(int)
with open("data.txt") as f:
for line in f:
tokens = [t.strip() for t in line.split(",")]
try:
sid = int(tokens[3])
mark = int(tokens[4])
except ValueError:
continue
d[sid] += mark
print d
输出:
defaultdict(<type 'int'>, {217387: 21, 216757: 116, 218382: 78, 216351: 185})
您可以将解析部分更改为其他任何内容(例如,使用csvreader
或执行其他验证)。这里的关键点是使用defaultdict(int)
并像这样更新它:
d[sid] += mark
答案 1 :(得分:0)
如果要在您提供的链接中调整解决方案,可以修改要解压缩的行。
这是一个想法(改编自OP的链接中的samplebias解决方案):
import csv
from collections import defaultdict
# a dictionary whose value defaults to a list.
data = defaultdict(list)
# open the csv file and iterate over its rows. the enumerate()
# function gives us an incrementing row number
for i, row in enumerate(csv.reader(open('data.csv', 'rb'))):
# skip the header line and any empty rows
# we take advantage of the first row being indexed at 0
# i=0 which evaluates as false, as does an empty row
if not i or not row:
continue
# unpack the columns into local variables
_, _, _, SID, mark = row#### <--- HERE, change what you unpack
# for each SID, add the mark the list
data[SID].append(float(mark))
# loop over each SID and its list of mark and calculate the sum
for zipcode, mark in data.iteritems():
print SID, sum(mark)
答案 2 :(得分:-1)
首先,要解析CSV,请使用csv
模块:
with open('data.csv', 'rb') as f:
data = csv.DictReader(f)
现在,您想通过Sid对它们进行分组。您可以通过排序,然后使用groupby
来完成此操作。 (如果相等的值始终是连续的,则不需要排序。)
siddata = sorted(data, key=operator.itemgetter('SId'))
sidgroups = itertools.groupby(siddata, operator.itemgetter('SId'))
现在,您想要对每个组中的值求和:
for key, group in sidgroups:
print('{}\t{}'.format(key, sum(int(value['Mark']) for value in group))
或者,您可以将其全部写入数据库,让SQLite找出如何为您完成此任务:
with open('data.csv', 'rb') as f, sqlite3.connect(':memory:') as db:
db.execute('CREATE TABLE data (SId, Mark)')
db.executemany('INSERT INTO data VALUES (:SId, :Mark)', csv.DictReader(f))
cursor = db.execute('SELECT SId, SUM(Mark) AS Mark FROM data GROUP BY SId')
for row in cursor:
print('{}\t{}'.format(row))