8
votes

Lire des colonnes spécifiques dans CSV à l'aide de Python

J'ai un fichier CSV qui ressemble à ceci: xxx

...

Comment puis-je lire uniquement les colonnes "AAA, DDD, FFF, FFF, GGG" en python et sauter les en-têtes? La sortie que je veux est une liste de tuples qui ressemble à ceci: [(1,4,3,20), (2,5,2,23), (4,6,1,22)]. Je pense écrire ces données à une sqldatabase plus tard.

J'ai mentionné ce message: lire des colonnes spécifiques à partir d'un fichier CSV avec module CSV? . Mais je ne pense pas que cela soit utile dans mon cas. Étant donné que mon .csv est assez gros avec des colonnes entières de colonnes, j'espère pouvoir dire à Python les noms de colonne que je veux, alors Python peut lire la ligne de colonnes spécifique à la ligne pour moi.


2 commentaires

Si vous pouvez utiliser une autre bibliothèque, Pandas peut vous aider facilement.


Je pense en utilisant Split (',') pour obtenir une liste d'en-têtes et obtenir l'index de la colonne que je veux, puis lisez le fichier CSV ... mais je me demande s'il y a de meilleurs moyens de faire cela.


7 Réponses :


4
votes
>>> import csv
>>> from collections import namedtuple
>>> from StringIO import StringIO
>>> def read_csv(file, columns, type_name="Row"):
...   try:
...     row_type = namedtuple(type_name, columns)
...   except ValueError:
...     row_type = tuple
...   rows = iter(csv.reader(file))
...   header = rows.next()
...   mapping = [header.index(x) for x in columns]
...   for row in rows:
...     row = row_type(*[row[i] for i in mapping])
...     yield row
... 
>>> testdata = """\
... AAA,bbb,ccc,DDD,eee,FFF,GGG,hhh
... 1,2,3,4,50,3,20,4
... 2,1,3,5,24,2,23,5
... 4,1,3,6,34,1,22,5
... 2,1,3,5,24,2,23,5
... 2,1,3,5,24,2,23,5
... """
>>> testfile = StringIO(testdata)
>>> for row in read_csv(testfile, "AAA GGG DDD".split()):
...   print row
... 
Row(AAA='1', GGG='20', DDD='4')
Row(AAA='2', GGG='23', DDD='5')
Row(AAA='4', GGG='22', DDD='6')
Row(AAA='2', GGG='23', DDD='5')
Row(AAA='2', GGG='23', DDD='5')

3 commentaires

J'aime vraiment ta solution. Cela fonctionne efficacement. Mais si je veux lire les colonnes dans un ordre différent, pour dire: "AAA, FFF, DDD, GGG"? Maintenant, le python lit les colonnes sélectionnées dans un ordre alphabétique.


Ça me donne une erreur rangée = rang_type (rangée [i] pour i en mappage) TypeError: __New __ () prend exactement 11 arguments (2 données)


Ni Yan: Il est tard, je suis devenu mignon et j'ai glissé dans l'une des différences d'interface entre Tuple et NamedTuple. J'ai édité le code et a fourni un exemple de session interactive qui l'utilise.



3
votes
import csv

DESIRED_COLUMNS = ('AAA','DDD','FFF','GGG')

f = open("myfile.csv")
reader = csv.reader(f)

headers = None
results = []
for row in reader:
    if not headers:
        headers = []
        for i, col in enumerate(row):
        if col in DESIRED_COLUMNS:
            # Store the index of the cols of interest
            headers.append(i)

    else:
        results.append(tuple([row[i] for i in headers]))

print results

1 commentaires

Roger's avec est une meilleure manipulation des fichiers. Je m'habitue toujours à l'utiliser



0
votes

Si vos fichiers et vos exigences sont relativement simples et définis, une fois que vous connaissez les colonnes souhaitées, j'utiliserais probablement Split () pour diviser chaque ligne de données dans une liste des entrées de colonne:

alist = aline.split('|')


0 commentaires

0
votes

Toutes les autres réponses sont bonnes, mais je pense qu'il serait préférable de ne pas charger toutes les données en même temps, car le fichier CSV pourrait être vraiment énorme. Je suggère d'utiliser un générateur.

with open('path/to/test.csv', 'rb') as f:
    for bbb, ccc in read_csv(f, [1, 2]):
        print bbb, ccc


0 commentaires

6
votes

Je réalise que la réponse a été acceptée, mais si vous souhaitez vraiment lire des colonnes nommées em> à partir d'un fichier CSV, vous devez utiliser un dicterreader code> (si vous êtes Ne pas utiliser Pandas code> c'est-à-dire).

>>> list(desired_cols)
[('1', '4', '3', '20'),
 ('2', '5', '2', '23'),
 ('4', '6', '1', '22'),
 ('2', '5', '2', '23'),
 ('2', '5', '2', '23')]


0 commentaires

1
votes

Contexte: Pour ce type de travail, vous devez utiliser l'incroyable bibliothèque Python Petl. Cela vous fera économiser beaucoup de travail et de frustration potentielle de faire «manuellement» avec le module CSV standard. AFAIK, les seules personnes qui utilisent toujours le module CSV sont celles qui n'ont pas encore découvert de meilleurs outils pour travailler avec des données tabulaires (Pandas, PETL, etc.), ce qui convient, mais si vous envisagez de travailler avec beaucoup de données dans Votre carrière de différentes sources étranges, apprendre quelque chose comme PETL est l'un des meilleurs investissements que vous puissiez faire. Pour commencer, ne devrait prendre que 30 minutes après avoir terminé Pip Install Petl. La documentation est excellente.

Réponse: Disons que vous avez la première table dans un fichier CSV (vous pouvez également charger directement à partir de la base de données à l'aide de PETL). Ensuite, vous le charriez simplement et procédez comme suit. P>

from petl import fromcsv, look, cut, tocsv    

    #Load the table
    table1 = fromcsv('table1.csv')
    # Alter the colums
    table2 = cut(table1, 'Song_Name','Artist_ID')
    #have a quick look to make sure things are ok.  Prints a nicely formatted table to your console
    print look(table2)
    # Save to new file
    tocsv(table2, 'new.csv')


0 commentaires

0
votes

Je pense que cela aidera.

csv p> xxx pré>

code p> xxx pré>

exemple p> xxx pré>

résultat p> xxx pré>

exemple2 p> xxx pré>

résultat2 p>

<__main__.get_csv.<locals>.RowObject object at 0x01408ED0>
<__main__.get_csv.<locals>.RowObject object at 0x01408E90>
<__main__.get_csv.<locals>.RowObject object at 0x01408F10>

for item in vs:
    print(item.f2)

E350
Venture "Extended Edition"
Grand Cheroke


0 commentaires