2017-10-16 4 views
0

J'essaie de faire des années de retour, moyenne de la note pour chaque année. Ce que j'essayais de faire était de créer un dictionnaire qui corresponde à year: grade, puis d'obtenir un autre dictionnaire de l'année: sum_of_grade, etc.Création d'un dictionnaire, extraction de tableau de moyenne

Il est à partir du fichier csv, qui a deux têtes: l'année et le grade

Year Grade 
2001 100 
2002 99 
2001 88 
2003 11 
2005 55 

Il y a beaucoup plus, mais je ne pense pas qu'il est nécessaire d'avoir l'ensemble des données. J'ai essayé d'être clair, mais si ce n'est toujours pas clair, s'il vous plaît faites le moi savoir.

Répondre

1

Il y a un problème lorsque vous utilisez ceci:

d = dict(zip(years,grades)) # dict year:grade

Prenez vos données d'entrée comme exemple, il va générer un dict comme:

{2001: 88, 2002: 99, 2003:11, 2005: 55} 

Parce que lorsqu'il y a une clé en double pendant le dictionnaire de construction, la valeur est redéfinie.

Alors, pour y parvenir, je recommande d'utiliser un autre dict générer méthode, faire quelque chose comme ceci:

def construct_values(file): 
    """ 
    Construct the values needed to graph the average grade of the class over time 

    Parameters 
    ---------- 
    file_path: A string. Absolute path to file. 

    Returns 
    ------- 
    years: array of integers 
    average_grades: array of floats 
    """ 
    years, average_grades = [], [] 
    # grades = []  This variable don't need anymore 
    d = {} 
    with open(file,'r') as f: 
     next(f) 
     for line in f: 
      year, grade = (s.strip() for s in line.split(',')) 

      # here is the begin line difference from your code 
      if year not in d: 
       d[year] = [int(grade), 1] 
      else: 
       d[year][0] += int(grade) 
       d[year][1] += 1 

     for year, grade_info in d.items(): 
      years.append(year) 
      average_grades.append(grade_info[0]/grade_info[1]) 
      # end difference from your code 

     return years, average_grades 

Dans le dictionnaire milieu d, la valeur enregistrer des informations sur [sum_of_grade, times_appeared_in_the_year ], donc quand vous itérez le dictionnaire, vous pouvez facilement utiliser sum_of_grade/times_appeared_in_the_year pour calculer la moyenne.

Et donc, vous n'avez pas besoin d'utiliser la variable supplémentaires grades

+0

Ce qui est avec i dans years.append()? Est-ce censé être l'année? En outre, je ne comprends pas comment les notes peuvent s'ajouter dans ce cas. – Mayjunejuly

+0

Oui, je suis désolé, c'est l'année. La note est ajoutée ici: '' 'd [année] = [grade, 1]' '', quand vous rencontrez * 2001, 100 *. Le dictionnaire du milieu sera {2001: [100, 1]}, puis rencontrera * 2001, 88 *. Le dictionnaire du milieu sera {2001: [188, 2], 2002: [99, 1]}. Parce que vous voulez simplement retourner la note moyenne, je pense que nous pouvons économiser la somme des notes et le nombre de notes dans une liste. Il n'est pas nécessaire d'ajouter une valeur réelle. – Ballack

+0

Vos codes fonctionnent, mais cela ne tient pas compte des commandes? parce qu'il est mélangé tout au long, par exemple à partir de 2001. – Mayjunejuly

0

Bien que créé en tant que dict(zip(years,grades)) la clé en double ne sera pas autorisée dans le dictionnaire. Donc, mieux vaut utiliser une autre méthode que le dictionnaire.

Une chose comme ça.

from itertools import groupby 
combined = zip(year,grade)  
for n,g in groupby(sorted(combined, key = lambda x:x[0]),key=lambda x:x[0]): 
    grades = [int(i[1])for i in g] 
    print 'year : %s average : %s' %(n,sum(grades)/len(grades)) 

Résultat:

year : 2001 average : 94 
year : 2002 average : 99 
year : 2003 average : 11 
year : 2005 average : 55 
1

Dès que vous voyez une table (fichier csv étant l'un), vous devriez penser Pandas (mon avis).

Voici une solution de pandas géants:

import pandas as pd 
import io 

csv = """Year,Grade 
2001,100 
2002,99 
2001,88 
2003,11 
2005,55""" 

df = pd.read_csv(io.StringIO(csv)) 

year_grade = {k: list(v) for k,v in df.groupby("Year")["Grade"]} 
year_avg_grade = df.groupby("Year")["Grade"].mean().to_dict() 

year_grade:

{2001: [100, 88], 2002: [99], 2003: [11], 2005: [55]} 

year_avg_grade:

{2001: 94, 2002: 99, 2003: 11, 2005: 55} 
+0

très vrai. Je comprends que les pandas fonctionnent bien ici. Mais pour une raison quelconque, cette affectation m'empêche d'utiliser des pandas. – Mayjunejuly