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.
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:
Pour ignorer la première ligne, appelez simplement:
next(inf)
Les fichiers en Python sont des itérateurs sur des lignes.
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
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)))
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 ...
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.
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()
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"])
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])
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
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)
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]
Je voudrais utiliser tail pour me débarrasser de la première ligne indésirable:
tail -n +2 $INFIL | whatever_script.py
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