组织csv数据并计算平均成绩

时间:2017-07-25 18:46:14

标签: python python-2.7 csv dictionary

我有一个类别和等级的样本csv数据,超过500行,它看起来像这样

courseid  title  teacher  avggpa  students As   Bs   Cs    Ds   Fs
101       Math   Stevens  3.15    105      25.2 45.1 16.7  10.1 2.9
101       Math   Stevens  2.98    95       20.2 30.1 30.5  11.5 5.4
101       Math   Smith    3.33    120      33.1 40.1 10.2  7.6  4.3
103      English Jane     3.55    108      20.5 16.2 16.5  20.5 10.2
103      English Jane     3.47    100      25.2 38.0 22.0  7.0  2.0
202      Science Roberts  2.67    80       12.0 35.0 27.5  12.5 8.3

(假设这些是逗号分隔的,我只是为了格式化目的而打字。而且百分比加起来不是100%但假装他们这样做了)

到目前为止,我所拥有的是:

with open(filename, 'rb') as f:
    reader = csv.reader(f, delimiter=',')
    next(reader, None)                        #to skip header
    self.data = list(reader)

case_list = []
for entry in self.data:
    case = {'course_number': entry[1], 'course_title': entry[2], 'teacher': entry[3]... #and so on for each header
    case_list.append(case)

所以我有一个字典列表,其中每个字典条目都是csv文件中的一行。

我的目标是将教授同一课程不止一次的教师的avggpa和As,Bs,Cs,Ds,Fs进行组合和平均。所以在我的例子中,我想平均Steven和Jane的等级,然后用视觉来表示。如果老师只教一门课程,我也想用视觉表示他的成绩。

我正在努力想出一种确定教师是否教授多门课程的方法。循环遍历列表并检查课程和教师是否已经在字典中,然后调用函数来平均gpas,如果是这样,但我似乎无法想出逻辑。

非常感谢任何帮助,如果需要更多说明,请告诉我。如果组织csv数据的方法比我最初做的更好,请告诉我!

2 个答案:

答案 0 :(得分:1)

我认为大熊猫是做这项工作的合适工具。虽然我不是专家,但经过快速谷歌搜索,我想出了这个:

import pandas as pd

df = pd.read_csv(filename, sep=',')
grouped = df.groupby(['title', 'teacher'])
average = grouped[['avgpa', 'As', 'Bs', 'Cs', 'Ds', 'Fs']].mean()

这应该是正确的,只有4行长。我希望这对你有所帮助。

答案 1 :(得分:0)

首先,请记住列表开始索引为0,因此您在每个字段中添加每个条目的行都会减1。从

开始
entry[0]

无论如何,你已经组织了一个dicts列表,其中每个dict代表给定课程的统计数据。出于您的目的,最好将您的信息整理到一个单词中,其中键是教师的姓名和课程ID,值是他们对该课程的总统计数。为此,您将初始化一个空的dict,然后迭代抛出csv的行,检查您的dict中是否已存在给定教师/ courseid的条目,如果是,则更新,否则添加。像这样:

stats = {}
for entry in self.data:
    # Convert type
    entry[3] = float(entry[3])
    entry[4] = float(entry[4])
    # Check if this teacher is already in the dict
    if not entry[0] + entry[2] in stats:
        # Add a new row
        stats[entry[0] + entry[2]] = {'total_students':entry[4], 'weighted_gpa':entry[4]*entry[3]}
    else:
        # Update this row
        stats[entry[0] + entry[2]]['weighted_gpa'] = stats[entry[0] + entry[2]]['weighted_gpa'] + entry[4]*entry[3]
        stats[entry[0] + entry[2]]['total_students'] = stats[entry[0] + entry[2]]['total_students'] + entry[4]

然后你可以浏览字典并获得平均gpas:

for teachercourse in stats:
    teachercourse['avg_gpa'] = teachercourse['weighted_gpa'] / teachercourse['total_students']

我保持平均gpas的可读性,但你可以添加'total_weighted_number_of_As'等来获取所需数据的完整列表