J'ai donc plusieurs fichiers csv qui représentent des données, dont chacun peut avoir différentes lignes de commentaires initiaux
import os import glob import csv def read_multicolumn_csv_files_into_dictionary(folderpath, dictionary): filepath = folderpath + '*.csv' files = sorted(glob.glob(filepath)) for file in files: data_set = file.replace(folderpath, '').replace('.csv', '') dictionary[data_set] = {} with open(file, 'r') as data_file: data_pipe = csv.DictReader(data_file) dictionary[data_set]['pt'] = [] dictionary[data_set]['sigma'] = [] for row in data_pipe: dictionary[data_set]['pt'].append(float(row['PT [GEV]'])) dictionary[data_set]['sigma'].append(float(row['D2(SIG)/DYRAP/DPT [NB/GEV]'])) return dictionary
Je voudrais lire uniquement les données pertinentes et leurs en-têtes, qui commencent par la ligne
PT [GEV], PT [GEV] LOW, PT [GEV] HIGH, D2(SIG)/DYRAP/DPT [NB/GEV]
Par conséquent, la stratégie à laquelle je penserais est de trouver le modèle PT [GEV]
et de commencer à lire à partir de là.
Cependant, je ne sais pas comment y parvenir en Python, quelqu'un pourrait-il m'aider à ce sujet?
Merci d'avance!
Au fait, la fonction que j'ai actuellement est
table_doi: 10.17182/hepdata.52402.v1/t7 name: Table 7 ... ABS(YRAP), < 0.1 SQRT(S) [GeV], 1960 PT [GEV], PT [GEV] LOW, PT [GEV] HIGH, D2(SIG)/DYRAP/DPT [NB/GEV] 67, 62, 72, 6.68 ... 613.5, 527, 700, 1.81E-07
qui ne fonctionne que si je supprime manuellement ces commentaires initiaux dans les fichiers csv.
5 Réponses :
En supposant que chaque fichier a une ligne commençant par PT [GEV]
:
import os import pandas as pd ... csvs = [] for file in files: with open(file) as f: for i, l in enumerate(f): if l.startswith('PT [GEV]'): csvs.append(pd.read_csv(file, skiprows = i)) break df = pd.concat(csvs)
Essayez ceci où il recherchera la ligne qui contient PT [GEV]
et s'il trouve le contient, il changera le m
pour être vrai et commencera à ajouter le reste de la date à la liste:
import csv contain= 'PT [GEV]' List=[] m=false with open('Users.csv', 'rt') as f: reader = csv.reader(f, delimiter=',') for row in reader: for field in row: if field == contain: m=true if m==true: List.append(row)
Ça a marché! Il renverrait une liste de liste, comment pensez-vous que je pourrais la transmettre à csv.DictReader
? Ou avez-vous une meilleure idée de le manipuler?
vous pouvez facilement convertir la liste en dictionnaire voir ce stackoverflow.com/questions/6900955/...
Merci, je vais essayer, désolé pour la réponse tardive.
Vous pouvez utiliser la méthode file.tell
pour enregistrer la position du pointeur de fichier pendant que vous lisez et ignorez les lignes jusqu'à ce que vous trouviez la ligne d'en-tête, à quel point vous pouvez utiliser la méthode file.seek
pour réinitialiser le pointeur de fichier au début de la ligne d'en-tête pour que csv.DictReader
puisse analyser le reste du fichier comme CSV valide:
with open(file, 'r') as data_file: while True: position = data_file.tell() line = next(data_file) if line.count(',') == 3: # or whatever condition your header line satisfies data_file.seek(position) # reset file pointer to the beginning of the header line break data_pipe = csv.DictReader(data_file) ...
C'est une belle façon de le faire! J'ai 20 entrées pour les données réelles, donc j'écris if line.count(',') == 19:
mais je récupère un dictionnaire vide. J'ai donc essayé d'imprimer la line
avant la if
déclaration et il ne semble que le while
est mis fin à la boucle une fois que le programme a trouvé la ligne d' en- tête réelle. Pensez-vous que le problème vient du passage de data_file
à data_pipe
?
Je créerais simplement une fonction d'aide pour amener votre lecteur csv au premier enregistrement:
def remove_comments_from_file(): file_name = "super_secret_file.csv" file = open(file_name, 'rU') csv_read_file = csv.reader(file) for row in csv_read_file: if row[0] == "PT [GEV]" break return csv_read_file
Quelque chose dans ce sens, lorsque le lecteur csv est renvoyé, il démarrera à votre premier enregistrement (dans cet exemple - 67, 62, 72, 6.68)
Merci pour votre réponse, mais comment manipuler le csv_read_file
renvoyé? J'ai essayé de le transmettre à la fonction mais il serait reconnu comme NoneType
, puis j'ai essayé de l'imprimer, mais la seule chose qui est montrée est <_csv.reader object at 0x1190d44b0>
.
Au fait, il y a des lignes vides qui pourraient poser des problèmes, j'ai donc ajouté une instruction if row != []:
Qui traite de cela.
le paiement startswith
. Vous pouvez également trouver des explications détaillées ici. https://cmdlinetips.com/2018/01/3-ways-to-read-a-file-and-skip-initial-comments-in-python/
J'ai déjà lu cette page Web, cependant, ce que j'essaie de faire est de trouver PT [GEV]
et de tout lire au-delà de ce point, alors que les lignes au-delà ne commencent pas nécessairement par PT [GEV]
.