web-dev-qa-db-fra.com

numpy loadtxt ignorer la première ligne

J'ai un petit problème lorsque j'essaie d'importer des données à partir de fichiers CSV avec la fonction loadtxt de numpy. Voici un exemple du type de fichiers de données que j'ai. 

Appelez-le 'datafile1.csv':

# Comment 1
# Comment 2
x,y,z 
1,2,3
4,5,6
7,8,9
...
...
# End of File Comment

Le script que je pensais fonctionner dans cette situation ressemble à ceci:

import numpy as np
FH = np.loadtxt('datafile1.csv',comments='#',delimiter=',',skiprows=1)

Mais je reçois une erreur:

ValueError: could not convert string to float: x

Cela me dit que les «skprows» du kwarg ne sautent pas l'en-tête, mais la première rangée de commentaires. Je pourrais simplement m'assurer que skiprows = 3, mais la complication est que j'ai un très grand nombre de fichiers, qui n'ont pas nécessairement tous le même nombre de lignes commentées en haut du fichier. Comment puis-je être sûr que lorsque j'utilise loadtxt, je ne reçois que les données réelles dans une situation comme celle-ci?

P.S. - Je suis ouvert aux solutions bash aussi. 

12
astromax

Ignorer la ligne de commentaire manuellement à l'aide de l'expression du générateur:

import numpy as np

with open('datafile1.csv') as f:
    lines = (line for line in f if not line.startswith('#'))
    FH = np.loadtxt(lines, delimiter=',', skiprows=1)
20
falsetru

Créez votre propre fonction de filtre personnalisée, telle que:

def skipper(fname):
    with open(fname) as fin:
        no_comments = (line for line in fin if not line.lstrip().startswith('#'))
        next(no_comments, None) # skip header
        for row in no_comments:
            yield row

a = np.loadtxt(skipper('your_file'), delimiter=',')
1
Jon Clements
def skipper(fname, header=False):
    with open(fname) as fin:
        no_comments = (line for line in fin if not line.lstrip().startswith('#'))
        if header:
            next(no_comments, None) # skip header
        for row in no_comments:
            yield row

a = np.loadtxt(skipper('your_file'), delimiter=',')

Ceci est juste une petite modification de la réponse de @Jon Clements en ajoutant un paramètre optionnel "en-tête", étant donné que dans certains cas, le fichier csv a des lignes de commentaire (commençant par #) mais pas la ligne d'en-tête.

0
JeffZheng