2017-07-25 75 views
1

我的班級樣本CSV數據超過500行,它看起來像這樣組織CSV數據和計算平均成績

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) 

所以我有字典的列表,其中每個dictio中nary條目是來自csv文件的一行。

我的目標是合併和平均來自教授同一課程的教師不止一次的avggpa和As,Bs,Cs,Ds,Fs。所以在我的例子中,我想平均Steven和Jane的課程成績,然後用視覺來表示。如果一位老師只教一門課程,我還想用視覺來代表他的成績。

我很努力想出一種方法來確定一位教師是否教授多門課程。按照循環遍歷列表的方式,檢查courseid和teacher是否已經在字典中,然後調用函數來平均gpas,但是我似乎無法想出邏輯。

任何幫助將不勝感激,如果需要更多的澄清,請讓我知道。如果還有比我最初做的更好的組織csv數據的方法,請讓我知道!

+4

除非你被要求不要,我建議使用熊貓這個項目。 – DyZ

+0

@DYZ這是一個自我項目,所以我一定會看看熊貓 –

回答

0

首先,請記住列表開始索引編號爲0,因此您添加每個條目的行在每個字段中都會關閉1。在

entry[0] 

開始不管怎麼說,你已經組織類型的字典,其中每個字典代表一個給定的課程的統計列表。出於您的目的,最好將單個詞典中的信息組織起來,其中關鍵是教師姓名和課程編號,其價值是其課程總數。要做到這一點,你需要初始化一個空字典,然後迭代拋出csv的行,檢查字典中是否已經存在一個給定教師/ 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] 

然後你就可以通過字典運行,並獲得平均GPA成績:

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

我把它保持在平均的GPA爲了可讀性,您可以添加「total_weighted_number_of_As」等,讓您充分期望的統計列表

+0

謝謝你,這是非常有益的!我從1開始索引,因爲我對第一列數據不感興趣,但是我忘了提及 –

+0

不用擔心!我正在談論這一行'case = {'course_number':entry [1] ...'should be'case = {'course_number':entry [0] ...'並且每個其他索引也應該使索引值減1 – A0A

+0

一些簡短的問題 - 在第6行中,您的意思是'weighted_gpa'而不是'weighted_total_gpa'?還有我在第9行得到一個TypeError:不能用'str'類型的非int乘以序列。這很奇怪,因爲如果我輸入[4] * 2或2 *輸入[3],它可以正常工作 –

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行長。我希望這對你有幫助。