3
votes

Suppression de lignes et de colonnes dans le module CSV python

Je promets que j'ai cherché et lu plusieurs pages de google avant de venir publier ce message. Une diligence raisonnable a été effectuée, je le jure.

J'essaie d'ouvrir un fichier CSV en python, de lire le fichier, d'y apporter des modifications, puis d'écrire un nouveau fichier.

Je suis arrivé jusqu'ici :

"Area","Area Id","Variable Name","Variable Id","Year","Value","Symbol","Md" 
"Afghanistan",2,"Total area of the country",4100,1977,65286.0,"E","",""
"Afghanistan",2,"Total area of the country",4100,1982,65286.0,"E","","" 
"Afghanistan",2,"Total area of the country",4100,1987,65286.0,"E","",""
"Afghanistan",2,"Total area of the country",4100,1992,65286.0,"E","","" 
"Afghanistan",2,"Total area of the country",4100,1997,65286.0,"E","",""
"Afghanistan",2,"Total area of the country",4100,2002,65286.0,"E","",""

Mais j'ai du mal à aller plus loin. Je veux supprimer certaines colonnes, mais je ne peux pas comprendre comment python connaîtra la différence entre une ligne et une colonne. Par exemple, les colonnes sont Area, Area ID, Year, Value , etc. Je veux seulement Area, Year, Value . J'ai essayé

for row in final_file:

final_file.writerow(row[0] + row[2] + row[4] + row[5])

mais j'ai continué à recevoir l'erreur suivante: IndexError: list index out of range

[Je voudrais aussi remplacer les cellules vides par un *, mais la colonne est la priorité]

Notez que je ne peux pas utiliser les pandas

Si possible, j'apprécierais vraiment que quelqu'un ne puisse pas simplement me le dire le code mais expliquez-le-moi pour que je puisse le comprendre moi-même.

TLDR: Comment puis-je supprimer les lignes vides du fichier CVS et n'écrire que certaines colonnes dans le nouveau fichier? strong>

import csv
def water_data ():
    with open('aquastat.csv', 'r') as csv_file:
        csv_reader = csv.reader(csv_file)
        final_file_name = "final_water.data.csv"
        final_file = open(final_file_name,'w')
        csv_writer = csv.writer(final_file,delimiter="\t")
        for row in csv_reader:
            csv_writer.writerow(row)


5 commentaires

Pouvez-vous nous donner une partie de votre contribution?


«Zone», «ID de zone», «Nom de variable», «ID de variable», «Année», «Valeur», «Symbole», «Md» «Afghanistan», 2, «Superficie totale du pays», 4100, 1977,65286,0, "E", "", "" "Afghanistan", 2, "Superficie totale du pays", 4100,1982,65286,0, "E", "", "" "Afghanistan", 2, "Total superficie du pays ", 4100,1987,65286,0," E "," "," "" Afghanistan ", 2," Superficie totale du pays ", 4100,1992,65286,0," E "," "," " "Afghanistan", 2, "Superficie totale du pays", 4100,1997,65286,0, "E", "", "" "Afghanistan", 2, "Superficie totale du pays", 4100,2002,65286,0, " E "," "," "


Pourriez-vous également ajouter votre sortie attendue pour l'entrée?


Je ne suis pas sûr. J'essaye juste de nettoyer les données. je voudrais que les données soient les mêmes mais sans la colonne ID de zone, ou sans lignes vides


@AshleyF avez-vous besoin de le faire en Python? sinon, vous pouvez utiliser une simple commande bash telle que cat File.csv | couper -d, -f1,5,6


3 Réponses :


0
votes

Cette ligne ne sera pas IndexError et écrira la ligne en ignorant les valeurs non existantes:

final_file.writerow ((row [i] for i in (0,2,5) if i

Cette ligne ne sera pas IndexError et écrira la ligne remplaçant les valeurs vides par une étoile:

final_file.writerow ((row [i] if i

Cette ligne ne sera pas non plus IndexError mais n'écrira pas la ligne:

if len (row)> 5: final_file.writerow ((row [i] for i in (0,2,5)))

Cette ligne ne sera pas non plus IndexError mais n'écrira aucune ligne du tout:

pass


0 commentaires

2
votes

J'ai essayé de vous fournir une réponse aussi proche que possible de ce que vous avez fait jusqu'à présent.

Area    Year    Value
Afghanistan     1977    65286.0
Afghanistan     1982    65286.0
Afghanistan     1987    65286.0
Afghanistan     1992    65286.0
Afghanistan     1997    65286.0
Afghanistan     2002    65286.0

  • Avant la ligne csv_writer.writerow (row) où vous sortez la ligne dans le fichier csv de sortie. J'ai ajouté la ligne row = [row [0], row [4], row [5]] où j'écrase le contenu du tableau row par un tableau contenant seulement 3 cellules, ces cellules sont respectivement extraites des colonnes Area , Year , Value
  • En plus de cela, j'ai ajouté une condition if if len (row)> = 6: pour vérifier que vous avez au moins assez d'éléments dans votre ligne pour extraire les colonnes jusqu'à Valeur .
  • pré>


0 commentaires

0
votes

Vous pouvez utiliser un DictReader et DictWriter pour modifier et écrire de manière sélective des colonnes spécifiques en utilisant leurs noms d'en-tête / colonne.

J'utiliserai io.StringIO pour simuler les fichiers

>>> g.seek(0)
0
>>> print(g.read())
Afghanistan,4100,65.286
Afghanistan,4100,65.286
Afghanistan,4100,65.286
Afghanistan,4100,65.286
Afghanistan,4100,65.286
Afghanistan,4100,65.286

Notez que le paramètre extrasaction de DictWriter doit être défini sur 'ignorer' car il y a des clés / champs supplémentaires dans l'original.

Si le fichier csv n'a pas de ligne d'en-tête, vous devez spécifier les noms de champ pour le DictWriter.


s = '''"Area","Area Id","Variable Name","Variable Id","Year","Value","Symbol","Md" 
"Afghanistan",2,"Total area of the country",4100,1977,65286.0,"E","",""
"Afghanistan",2,"Total area of the country",4100,1982,65286.0,"E","","" 
"Afghanistan",2,"Total area of the country",4100,1987,65286.0,"E","",""
"Afghanistan",2,"Total area of the country",4100,1992,65286.0,"E","","" 
"Afghanistan",2,"Total area of the country",4100,1997,65286.0,"E","",""
"Afghanistan",2,"Total area of the country",4100,2002,65286.0,"E","",""'''

f = io.StringIO(s)
g = io.StringIO()

reader = csv.DictReader(f)
writer = csv.DictWriter(g, fieldnames=["Area","Variable Id","Value"], extrasaction='ignore')

for row in reader:
    #process row values?
    row['Value'] = float(row['Value']) / 1000
    writer.writerow(row)


0 commentaires