web-dev-qa-db-fra.com

Lors du traitement de données CSV, comment ignorer la première ligne de données?

Je demande à Python d'imprimer le nombre minimal d'une colonne de données CSV, mais la rangée supérieure correspond au numéro de colonne et je ne veux pas que Python prenne la rangée supérieure en compte. Comment puis-je m'assurer que Python ignore la première ligne?

C'est le code jusqu'à présent:

import csv

with open('all16.csv', 'rb') as inf:
    incsv = csv.reader(inf)
    column = 1                
    datatype = float          
    data = (datatype(column) for row in incsv)   
    least_value = min(data)

print least_value

Pourriez-vous également expliquer ce que vous faites, pas seulement donner le code? Je suis très nouveau sur Python et je voudrais être sûr de tout comprendre.

89
user1496646

Vous pouvez utiliser une instance de la classe csv class du module Sniffer pour déduire le format d'un fichier CSV et déterminer si une ligne d'en-tête est présente ainsi que la fonction intégrée next() pour ignorer uniquement la première ligne. quand c'est nécessaire:

import csv

with open('all16.csv', 'r', newline='') as file:
    has_header = csv.Sniffer().has_header(file.read(1024))
    file.seek(0)  # Rewind.
    reader = csv.reader(file)
    if has_header:
        next(reader)  # Skip header row.
    column = 1
    datatype = float
    data = (datatype(row[column]) for row in reader)
    least_value = min(data)

    print(least_value)

Puisque datatype et column sont codés en dur dans votre exemple, il serait légèrement plus rapide de traiter la row comme ceci:

    data = (float(row[1]) for row in reader)

Remarque: le code ci-dessus concerne Python 3.x. Pour Python 2.x, utilisez la ligne suivante pour ouvrir le fichier à la place de ce qui est affiché:

with open('all16.csv', 'rb') as file:
95
martineau

Pour ignorer la première ligne, appelez simplement:

next(inf)

Les fichiers en Python sont des itérateurs sur des lignes.

48
jfs

Vous utiliserez normalement next(incsv) qui avance l'itérateur d'une ligne, vous sautez donc l'en-tête. L'autre (disons que vous vouliez sauter 30 lignes) serait:

from itertools import islice
for row in islice(incsv, 30, None):
    # process
20
Jon Clements

Dans un cas d'utilisation similaire, je devais ignorer les lignes gênantes avant la ligne avec mes noms de colonnes actuels. Cette solution a bien fonctionné. Lisez d'abord le fichier, puis passez la liste à csv.DictReader.

with open('all16.csv') as tmp:
    # Skip first line (if any)
    next(tmp, None)

    # {line_num: row}
    data = dict(enumerate(csv.DictReader(tmp)))
18
Maarten

Emprunté à livre de cuisine en python
Un code de modèle plus concis pourrait ressembler à ceci: 

import csv
with open('stocks.csv') as f:
    f_csv = csv.reader(f) 
    headers = next(f_csv) 
    for row in f_csv:
        # Process row ...
9
shin

utilisez csv.DictReader au lieu de csv.Reader . Si le paramètre nom de champ est omis, les valeurs de la première ligne du fichier csv seront utilisées comme noms de champ. vous pourrez alors accéder aux valeurs de champ en utilisant la ligne ["1"], etc.

6
iruvar

Le nouveau paquet "pandas" pourrait être plus pertinent que "csv". Le code ci-dessous lira un fichier CSV, interprétant par défaut la première ligne comme en-tête de colonne et recherchant le minimum entre les colonnes.

import pandas as pd

data = pd.read_csv('all16.csv')
data.min()
2
Finn Årup Nielsen

Eh bien, ma mini bibliothèque d'empaquetage ferait aussi l'affaire.

>>> import pyexcel as pe
>>> data = pe.load('all16.csv', name_columns_by_row=0)
>>> min(data.column[1])

En attendant, si vous savez ce qu'est l'index de colonne d'en-tête 1, par exemple "Colonne 1", vous pouvez le faire à la place:

>>> min(data.column["Column 1"])
1
chfw

Pour moi, le moyen le plus simple consiste à utiliser la gamme. 

import csv

with open('files/filename.csv') as I:
    reader = csv.reader(I)
    fulllist = list(reader)

# Starting with data skipping header
for item in range(1, len(fulllist)): 
    # Print each row using "item" as the index value
    print (fulllist[item])  
1
Clint Hart

La documentation du module CSV Python 3 fournit cet exemple:

with open('example.csv', newline='') as csvfile:
    dialect = csv.Sniffer().sniff(csvfile.read(1024))
    csvfile.seek(0)
    reader = csv.reader(csvfile, dialect)
    # ... process CSV file contents here ...

La Sniffer essaiera de détecter automatiquement de nombreux éléments du fichier CSV. Vous devez explicitement appeler sa méthode has_header() pour déterminer si le fichier a une ligne d’en-tête. Si tel est le cas, ignorez la première ligne lors de l'itération des lignes CSV. Vous pouvez le faire comme ça:

if sniffer.has_header():
    for header_row in reader:
        break
for data_row in reader:
    # do something with the row
1
Lassi

Parce que cela est lié à quelque chose que je faisais, je vais partager ici. 

Que se passe-t-il si nous ne sommes pas sûrs qu'il existe un en-tête et que vous ne souhaitez pas non plus importer de renifleur ou autre? 

Si votre tâche est simple, telle qu'imprimer ou ajouter une liste ou un tableau, vous pouvez simplement utiliser une instruction if:

# Let's say there's 4 columns
with open('file.csv') as csvfile:
     csvreader = csv.reader(csvfile)
# read first line
     first_line = next(csvreader)
# My headers were just text. You can use any suitable conditional here
     if len(first_line) == 4:
          array.append(first_line)
# Now we'll just iterate over everything else as usual:
     for row in csvreader:
          array.append(row)
0
Roy W.

Python 3.X

Poignées UTF8 BOM + HEADER

C'était assez frustrant que le module csv ne puisse pas facilement obtenir l'en-tête, il y a aussi un bogue avec la nomenclature UTF-8 (premier caractère du fichier) . Cela fonctionne pour moi en utilisant uniquement le module csv:

import csv

def read_csv(self, csv_path, delimiter):
    with open(csv_path, newline='', encoding='utf-8') as f:
        # https://bugs.python.org/issue7185
        # Remove UTF8 BOM.
        txt = f.read()[1:]

    # Remove header line.
    header = txt.splitlines()[:1]
    lines = txt.splitlines()[1:]

    # Convert to list.
    csv_rows = list(csv.reader(lines, delimiter=delimiter))

    for row in csv_rows:
        value = row[INDEX_HERE]
0
Christophe Roussy

Je voudrais utiliser tail pour me débarrasser de la première ligne indésirable:

tail -n +2 $INFIL | whatever_script.py 
0
Karel Adams

ajoutez simplement [1:]

exemple ci-dessous:

data = pd.read_csv("/Users/xyz/Desktop/xyxData/xyz.csv", sep=',', header=None)**[1:]**

cela fonctionne pour moi dans iPython

0
aybuke