4 votes

Python Pandas lire un fichier csv avec une longueur de préambule variable

Bonjour, j'utilise pandas pour lire une série de fichiers et les concaténer dans un dataframe. Mes fichiers ont beaucoup de données inutiles au début, de longueur variable, que je veux ignorer. pd.read_csv() a la méthode skiprows. J'ai écrit une fonction pour gérer ce cas, mais je dois ouvrir le fichier deux fois pour que ça fonctionne. Y a-t-il un moyen meilleur?

HEADER = '#Start'

def header_index(file_name):
    with open(file_name) as fp:
        for ind, line in enumerate(fp):
            if line.startswith(HEADER):
                return ind

for row in directories:
    path2file = '%s%s%s' % (path2data, row, suffix)
    myDF = pd.read_csv(path2file, skiprows=header_index(path2file), header=0, delimiter='\t')

Toute aide serait grandement appréciée.

1voto

jottbe Points 3535

Cela serait maintenant possible (ne sais pas si c'était possible à l'époque) comme suit :

pos = 0
oldpos = None

while pos != oldpos:  # assurez-vous que nous arrêtons la lecture, au cas où nous atteindrions la fin du fichier
    line = fp.readline()
    if line.startswith(HEADER):
        # définir la position de lecture au début de la ligne
        # afin que pandas puisse lire l'en-tête
        fp.seek(pos)
        break
    oldpos = pos
    pos = fp.tell()    # retenir cette position comme le début de la ligne suivante

pd.read_csv(fp, ...vos options ici...)

-1voto

maxschlepzig Points 3578

Étant donné que read_csv() accepte également un objet de type fichier, vous pouvez ignorer les lignes indésirables en amont avant de passer cet objet --- plutôt que de passer le nom du fichier.

Exemple :

Remplacez

df = pd.read_csv(filename, skiprows=no_junk_lines(filename), ...)

par :

def forward_csv(f, prefix):
    pos = 0
    while True:
        line = f.readline()
        if not line or line.startswith(prefix):
            f.seek(pos)
            return f
        pos += len(line.encode('utf-8'))

df = pd.read_csv(forward_csv(open(filename), HEADER), ...)

Notes :

  • readline() renvoie une chaîne vide lorsque la fin du fichier est atteinte
  • ne pas invoquer tell() pour suivre la position évite certains appels système lseek
  • la dernière ligne de forward_csv() suppose que votre fichier d'entrée est encodé en ASCII ou UTF-8 - si ce n'est pas le cas, vous devez ajuster cette ligne

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X