0
votes

Lecture d'un fichier texte avec des colonnes numériques de différentes longueurs

J'ai un fichier texte, généré par un programme Fortran, avec le format plutôt étrange (et sûrement ennuyeux): xxx

Je veux lire séparément les quatre premières et les quatre dernières colonnes , les stocker dans des tableaux numpus. Utilisation de numpy.genfromtxt, j'ai facilement reçu les données des quatre premières colonnes: xxx

mais lorsque vous essayez de faire de même pour les quatre autres colonnes xxx

J'ai eu une longue liste de messages d'erreur, qui semblent être liées aux cellules manquantes dans les quatre premières colonnes. xxx

Toute astuce ou suggestions sur la façon de résoudre ce problème?


4 commentaires

Avez-vous essayé de passer \ t comme le paramètre délimiter = ?


Vous obtenez un message d'erreur de lecture dans les colonnes complètes sans les lignes manquantes par rapport à l'autre? Avez-vous essayé d'utiliser l'argument Skip_footer à la place de max_rows


Quelle est la taille du fichier, pouvez-vous le faire dans un éditeur de texte qui a Colonne Caractéristiques d'édition avant d'essayer de l'utiliser ??


Délimiteur peut être une liste des largeurs de colonne. Il semble que vous puissiez lire toutes les lignes dans genfromtxt , obtenir nan pour les valeurs manquantes.


4 Réponses :


1
votes

Malheureusement, les colonnes ne semblent pas avoir la même largeur (10 pour les quatre premiers champs, puis 11). Si tel est le cas, le Delimiter = Option de numpy.genfromtxt pourrait vous aider.

Voici une solution alternative pour lire les 4 champs à partir de la colonne 37: xxx


1 commentaires

Cela a fonctionné! Je venais de régler la longueur de la chaîne de la compréhension de la liste de 37 à 41 et cela a fonctionné bien. Merci à vous et à tous les autres qui me sont habilités à m'attaquer à ce problème ennuyeux!



0
votes

Si le format du fichier est toujours le même, cela fera:

import numpy as np

def squash(obj):
    return [[float(element) for element in column if element.strip() != ''] for column in obj]

with open('results.out') as f:
    data = f.read()

lines = data.split('\n')

number_width = 6
number_spacing = 4

result = squash(zip(*[[line[i:i + number_width] for i in range(0, len(line), number_width + number_spacing)]
                      for line in lines]))

first_four_cols = np.array(result[0:4]).T
last_four_cols = np.array(result[4:]).T


4 commentaires

Bien qu'une solution élégante, cela n'a pas fonctionné. Il retourne les deux tableaux vides.


C'est étrange; ça marche pour moi. Est-ce que mon hypothèse est que le format du fichier est toujours comme vous l'avez montré dans la question invalide? Alternativement, le nom de fichier est-il correct?


Le nom de fichier n'est certainement pas le problème, car je recevrais une erreur avant même d'atteindre l'appel à la fonction de courge. En fait, les données semblent être lues correctement et les lignes sont également remplies. Le problème semble être dans la fonction de courge, qui renvoie une liste vide.


Je ne sais pas comment l'expliquer car cela a fonctionné pour moi avec les données que vous avez données dans la question. Néanmoins, puisque vous avez résolu le problème, je suppose que tout va bien!



0
votes

avec une copie-n-pâte au fichier xxx

qui a presque l'air juste; Je pense que l'extra nan proviennent de signes négatifs mal placés. xxx


2 commentaires

Cette solution n'a pas fonctionné car elle lit les points de données de la colonne et ne renvoie pas les données en deux matrices distinctes, une contenant les quatre premières colonnes et l'autre contenant les quatre derniers.


Il est facile de trancher les deux parties de data , data [: x,: y] etc.



0
votes

Bien que ce soit certainement différent des formats délimités tels que .csv code> (et peut donc être gênant à certains), les langues de force et similaires utilisent souvent des formats de largeur fixe comme cet exemple. En effet, ils fonctionnent très bien pour les fichiers plus gros et correspondent souvent directement à la manière dont les données sont représentées en mémoire, ce qui facilite la coéquipie de ces langues.

Je ne suis pas sûr que votre exemple contient les données complètes (Stackoverflow peut se débarrasser de certains espaces pour vous). Mais je m'attends à ce que, lorsque vous lisez directement le fichier directement, chaque colonne sera exactement de 10 caractères et vous pourriez la lire comme ceci: P>

def convert(s):
    try:
        return float(s)
    except ValueError:
        return None


data = []
size = 10
with open('input.data', 'r') as f:
    for line in f:
        # process line, minus the EOL (len(line)-1)
        data.append([convert(line[0+i:size+i]) for i in range(0, len(line)-1, size)])


1 commentaires

Cette solution n'a pas fonctionné car elle lit les points de données de la colonne et ne renvoie pas les données dans deux tableaux (ou listes) distincts, une contenant les quatre premières colonnes et l'autre contenant les quatre derniers.