2017-06-13 1 views
2

D'abord, je veux commencer en disant que je suis pas vous demander d'écrire du code. Je veux seulement discuter et se nourrir de retour sur ce qui serait la meilleure façon de s'y prendre pour écrire ce programme parce que je suis coincé sur trouver comment briser le problème.Lire un fichier CSV dans un dictionnaire?

Mon programme est censé ouvrir un fichier CSV qui contient 7 colonnes:

Name of the state,Crop,Crop title,Variety,Year,Unit,Value. 

Voici une partie du fichier:

Indiana,Corn,Genetically engineered (GE) corn,Stacked gene varieties,2012,Percent of all corn planted,60 
Indiana,Corn,Genetically engineered (GE) corn,Stacked gene varieties,2013,Percent of all corn planted,73 
Indiana,Corn,Genetically engineered (GE) corn,Stacked gene varieties,2014,Percent of all corn planted,78 
Indiana,Corn,Genetically engineered (GE) corn,Stacked gene varieties,2015,Percent of all corn planted,76 
Indiana,Corn,Genetically engineered (GE) corn,Stacked gene varieties,2016,Percent of all corn planted,75 
Indiana,Corn,Genetically engineered (GE) corn,All GE varieties,2000,Percent of all corn planted,11 
Indiana,Corn,Genetically engineered (GE) corn,All GE varieties,2001,Percent of all corn planted,12 
Indiana,Corn,Genetically engineered (GE) corn,All GE varieties,2002,Percent of all corn planted,13 
Indiana,Corn,Genetically engineered (GE) corn,All GE varieties,2003,Percent of all corn planted,16 
Indiana,Corn,Genetically engineered (GE) corn,All GE varieties,2004,Percent of all corn planted,21 
Indiana,Corn,Genetically engineered (GE) corn,All GE varieties,2005,Percent of all corn planted,26 
Indiana,Corn,Genetically engineered (GE) corn,All GE varieties,2006,Percent of all corn planted,40 
Indiana,Corn,Genetically engineered (GE) corn,All GE varieties,2007,Percent of all corn planted,59 
Indiana,Corn,Genetically engineered (GE) corn,All GE varieties,2008,Percent of all corn planted,78 
Indiana,Corn,Genetically engineered (GE) corn,All GE varieties,2009,Percent of all corn planted,79 
Indiana,Corn,Genetically engineered (GE) corn,All GE varieties,2010,Percent of all corn planted,83 
Indiana,Corn,Genetically engineered (GE) corn,All GE varieties,2011,Percent of all corn planted,85 
Indiana,Corn,Genetically engineered (GE) corn,All GE varieties,2012,Percent of all corn planted,84 
Indiana,Corn,Genetically engineered (GE) corn,All GE varieties,2013,Percent of all corn planted,85 
Indiana,Corn,Genetically engineered (GE) corn,All GE varieties,2014,Percent of all corn planted,88 
Indiana,Corn,Genetically engineered (GE) corn,All GE varieties,2015,Percent of all corn planted,88 
Indiana,Corn,Genetically engineered (GE) corn,All GE varieties,2016,Percent of all corn planted,86 

Ensuite, lisez chaque ligne dans un dictionnaire. Il y a beaucoup de lignes dans ce fichier texte, les seules lignes que je veux/besoin sont les lignes dont la colonne Variété lit « Toutes les variétés transgéniques. » Veuillez noter que chaque état a également plusieurs lignes. L'étape suivante consiste à utiliser une entrée utilisateur d'une culture et à examiner uniquement les données pour cette culture. L'étape finale consiste à déterminer (pour chaque état) quelle est la valeur max et min et l'année correspondante et à l'imprimer.

La façon dont je pensais aller à c'était peut-être créer un jeu pour chaque ligne, vérifier si « Toutes les variétés GE » était dans le jeu et si on ajoute ensuite que dans un dictionnaire. Et puis faire quelque chose de similaire pour la culture?

Mon plus grand dilemme est probablement 1.) Je ne sais pas comment aller d'ignorer les lignes qui ne contiennent pas « Toutes les variétés génétiquement modifiées. » Est-ce que je fais cela avant ou après avoir créé le dictionnaire? et 2.) Je sais comment créer un dictionnaire avec une valeur et une clé, mais comment pourrais-je aller à ajouter le reste des valeurs à la clé? Faites-vous cela avec des ensembles? ou des listes?

+1

Qu'est-ce qui va être la clé et quelle sera la valeur? –

+0

Il existe un module 'csv' dans la bibliothèque standard que vous pouvez utiliser. –

+0

@DmitryPolonskiy la clé est censée être le nom de l'état et la valeur est censée être le nom de la culture, la variété, l'année et la valeur. –

Répondre

0

Comme mentionné précédemment, vous pouvez utiliser le module csv pour lire dans le fichier csv. Je ne savais pas exactement comment vous vouliez que les données structurées après la clé state, mais je pensais qu'il pourrait être plus agréable de pouvoir rechercher chaque crop_title particulier, puis être en mesure d'accéder à la value pour chaque année séparément.

In[33]: from collections import defaultdict 
    ...: from csv import reader 
    ...: 
    ...: crops = defaultdict(lambda: defaultdict(dict)) 
    ...: with open('hmm.csv', 'r') as csvfile: 
    ...:  cropreader = reader(csvfile) 
    ...:  for row in cropreader: 
    ...:   state, crop_type, crop_title, variety, year, unit, value = row 
    ...:   if variety == 'All GE varieties': 
    ...:    crops[state][crop_title][year] = value 
    ...: 
In[34]: crops 
Out[34]: 
defaultdict(<function __main__.<lambda>>, 
      {'Indiana': defaultdict(dict, 
         {'Genetically engineered (GE) corn': {'2000': '11', 
          '2001': '12', 
          '2002': '13', 
          '2003': '16', 
          '2004': '21', 
          '2005': '26', 
          '2006': '40', 
          '2007': '59', 
          '2008': '78', 
          '2009': '79', 
          '2010': '83', 
          '2011': '85', 
          '2012': '84', 
          '2013': '85', 
          '2014': '88', 
          '2015': '88', 
          '2016': '86'}})}) 
In[35]: crops['Indiana']['Genetically engineered (GE) corn']['2000'] 
Out[35]: '11' 
In[36]: crops['Indiana']['Genetically engineered (GE) corn']['2015'] 
Out[36]: '88' 

Vous pouvez également convertir year et value en entiers comme celui-ci crops[state][crop_title][int(year)] = int(value) qui vous permettra de faire des appels comme celui-ci (où la valeur de retour est un entier):

In[38]: crops['Indiana']['Genetically engineered (GE) corn'][2015] 
Out[38]: 88 
0

Déterminer si « Toutes les variétés GE » est dans la chaîne est relativement simple - utiliser le mot-clé in:

Pour la structure de données, je suis partie à la liste des dictionnaires, où chaque dictionnaire a un ensemble défini de clés:

myList = [ {}, {}, {}, ... ] 

le problème dans ce cas est que je ne suis pas sûr de ce que vous utilisez comme la clé, si chaque champ est une valeur. Rappelez-vous aussi la commande split() peut aider:

varieties = [] 
with open(datafile, 'r') as infile: 
    for line in file: 
     if "All GE varieties" in line: 
      varieties.append(line.split(',')) 

Cela vous donne une liste (variétés) contenant des listes, chacun des champs individuels de chaque ligne.

Quelque chose comme ceci:

varieties = [['Indiana','Corn','Genetically engineered (GE) corn','All GE varieties','2000','Percent of all corn planted','11'], ['Indiana','Corn','Genetically engineered (GE) corn','All GE varieties','2001','Percent of all corn planted','12'], ... ] 

De là, il serait assez facile de choisir l'état ou l'année, etc., en utilisant des tranches (tableau 2D).

0

je mets vos données dans un fichier nommé "crop_data.csv". Voici un code qui utilise le module standard csv pour lire chaque ligne dans son propre dictionnaire. Nous utilisons un test simple if pour nous assurer que nous gardons seulement les lignes où 'Variety' == 'All GE varieties', et nous stockons les données pour chaque état dans all_data, qui est un dictionnaire de listes, une liste par état. Puisque l'état 'Nom' est utilisé comme clé dans all_data, nous n'avons pas besoin de le garder dans la dictée row, de même nous pouvons rejeter la 'Variété', puisque nous n'avons plus besoin de cette information.

Une fois toutes les données rassemblées, nous pouvons l'imprimer en utilisant le module json.

Puis nous bouclons all_data, état par état, et calculons son maximum et son minimum.

import csv 
from collections import defaultdict 
import json 

filename = 'crop_data.csv' 

fieldnames = 'Name,Crop,Title,Variety,Year,Unit,Value'.split(',') 

all_data = defaultdict(list) 

with open(filename) as csvfile: 
    reader = csv.DictReader(csvfile, fieldnames=fieldnames) 
    for row in reader: 
     # We only want 'All GE varieties' 
     if row['Variety'] == 'All GE varieties': 
      state = row['Name'] 
      # Get rid of unneeded fields 
      del row['Name'], row['Variety'] 
      # Store it as a plain dict 
      all_data[state].append(dict(row)) 

# Show all the data 
print(json.dumps(all_data, indent=4)) 

#Find minimums & maximums 

# Extract the 'Value' field from dict d and convert it to a number 
def value_key(d): 
    return int(d['Value']) 

for state, data in all_data.items(): 
    print(state) 
    row = min(data, key=value_key) 
    print('min', row['Value'], row['Year']) 

    row = max(data, key=value_key) 
    print('max', row['Value'], row['Year']) 

sortie

{ 
    "Indiana": [ 
     { 
      "Crop": "Corn", 
      "Title": "Genetically engineered (GE) corn", 
      "Year": "2000", 
      "Unit": "Percent of all corn planted", 
      "Value": "11" 
     }, 
     { 
      "Crop": "Corn", 
      "Title": "Genetically engineered (GE) corn", 
      "Year": "2001", 
      "Unit": "Percent of all corn planted", 
      "Value": "12" 
     }, 
     { 
      "Crop": "Corn", 
      "Title": "Genetically engineered (GE) corn", 
      "Year": "2002", 
      "Unit": "Percent of all corn planted", 
      "Value": "13" 
     }, 
     { 
      "Crop": "Corn", 
      "Title": "Genetically engineered (GE) corn", 
      "Year": "2003", 
      "Unit": "Percent of all corn planted", 
      "Value": "16" 
     }, 
     { 
      "Crop": "Corn", 
      "Title": "Genetically engineered (GE) corn", 
      "Year": "2004", 
      "Unit": "Percent of all corn planted", 
      "Value": "21" 
     }, 
     { 
      "Crop": "Corn", 
      "Title": "Genetically engineered (GE) corn", 
      "Year": "2005", 
      "Unit": "Percent of all corn planted", 
      "Value": "26" 
     }, 
     { 
      "Crop": "Corn", 
      "Title": "Genetically engineered (GE) corn", 
      "Year": "2006", 
      "Unit": "Percent of all corn planted", 
      "Value": "40" 
     }, 
     { 
      "Crop": "Corn", 
      "Title": "Genetically engineered (GE) corn", 
      "Year": "2007", 
      "Unit": "Percent of all corn planted", 
      "Value": "59" 
     }, 
     { 
      "Crop": "Corn", 
      "Title": "Genetically engineered (GE) corn", 
      "Year": "2008", 
      "Unit": "Percent of all corn planted", 
      "Value": "78" 
     }, 
     { 
      "Crop": "Corn", 
      "Title": "Genetically engineered (GE) corn", 
      "Year": "2009", 
      "Unit": "Percent of all corn planted", 
      "Value": "79" 
     }, 
     { 
      "Crop": "Corn", 
      "Title": "Genetically engineered (GE) corn", 
      "Year": "2010", 
      "Unit": "Percent of all corn planted", 
      "Value": "83" 
     }, 
     { 
      "Crop": "Corn", 
      "Title": "Genetically engineered (GE) corn", 
      "Year": "2011", 
      "Unit": "Percent of all corn planted", 
      "Value": "85" 
     }, 
     { 
      "Crop": "Corn", 
      "Title": "Genetically engineered (GE) corn", 
      "Year": "2012", 
      "Unit": "Percent of all corn planted", 
      "Value": "84" 
     }, 
     { 
      "Crop": "Corn", 
      "Title": "Genetically engineered (GE) corn", 
      "Year": "2013", 
      "Unit": "Percent of all corn planted", 
      "Value": "85" 
     }, 
     { 
      "Crop": "Corn", 
      "Title": "Genetically engineered (GE) corn", 
      "Year": "2014", 
      "Unit": "Percent of all corn planted", 
      "Value": "88" 
     }, 
     { 
      "Crop": "Corn", 
      "Title": "Genetically engineered (GE) corn", 
      "Year": "2015", 
      "Unit": "Percent of all corn planted", 
      "Value": "88" 
     }, 
     { 
      "Crop": "Corn", 
      "Title": "Genetically engineered (GE) corn", 
      "Year": "2016", 
      "Unit": "Percent of all corn planted", 
      "Value": "86" 
     } 
    ] 
} 
Indiana 
min 11 2000 
max 88 2014 

Notez que dans ces données, il y a 2 ans avec la valeur de 88. Vous pourrait utiliser une fonction clé que colombophile value_key si vous voulez rompre les liens par année. Ou vous pouvez utiliser value_key pour trier la liste complète de l'état data, de sorte que vous pouvez facilement extraire tous les enregistrements les plus bas et les plus élevés. Par exemple, dans cette boucle for state, data faire

data.sort(key=value_key) 
print(json.dumps(data, indent=4)) 

et il imprime tous les enregistrements de cet état dans l'ordre numérique.

+0

Je suppose que cela dépend de ce que l'OP veut, mais cela ressemble beaucoup à la duplication. La seule chose qui change dans chacun de ces dicts intérieurs est la paire de clés 'year/value'. –

+0

@DeliriousLettuce Vrai, mais c'est seulement dans les données d'échantillon données, les vraies données peuvent avoir plus de variété. Mais s'ils veulent abandonner certains de ces autres domaines, j'ai déjà montré comment faire cela. –