1
votes

Lire un fichier de colonne en Julia

Je n'aimerais pas beaucoup piéger dans la langue juste pour lire un fichier avec des données numériques arrangées par colonnes. Existe-t-il un moyen simple de le faire maintenant dans Julia 1.1? Étonnamment, cette tâche simple ne figure pas dans le manuel. En python, on ferait quelque chose comme ceci:

def read2col(filename, length):
    data = []
    for line in open(filename,'r'):
        for word in line.split():
            data.append(word)

data = np.reshape(data,(length,2))
data = np.asarray(data, dtype=np.float64)
return data


0 commentaires

3 Réponses :


1
votes

(non testé)

asfloat64(s) = try x = parse(Float64, s); return x catch; return missing; end
read2col(fname, len) = asfloat64.(reshape(split(read(fname, String), r"\s+"), (len, 2)))

ou même

function read2col(filename, len)
    asfloat64(s) = try x = parse(Float64, s); return x catch; return missing; end
    data = []
    for word in split(read(filename, String), r"\s+")
        push!(data, word)
    end
    data = reshape(data,(len, 2))
    data = asfloat64.(data)
    return data
end


2 commentaires

Merci pour la réponse. Je n'ai pas encore essayé la dernière suggestion mais la première est presque là, il suffit de supprimer le dernier caractère data [end] = "" .


Vous pouvez couper le fichier avec trim (read (fname, String)) pour vous débarrasser de vos lignes vides de fin. La solution DelimitedFiles gère bien les lignes vides de fin, mais se bloque si l'une des entrées n'est pas numérique. Vous devrez peut-être également décider quoi faire si le nombre d'entrées n'est pas pair, car cela ferait également planter les fonctions.



4
votes

Il existe déjà une fonction intégrée dans Julia qui fait exactement cela:

julia>  reshape(readdlm("file.txt")',:,2)
6×2 reshape(::LinearAlgebra.Adjoint{Float64,Array{Float64,2}}, 6, 2) with eltype Float64:
 1.0   7.0
 2.0   8.0
 3.0   9.0
 4.0  10.0
 5.0  11.0
 6.0  12.0

Faisons un tour:

shell> more file.txt
1 2 3
4 5 6
7 8 9
10 11 12

julia>  reshape(readdlm("file.txt"),:,2)
6×2 Array{Float64,2}:
  1.0   8.0
  4.0  11.0
  7.0   3.0
 10.0   6.0
  2.0   9.0
  5.0  12.0

ou si vous voulez un ordre différent transposez simplement avec '

using DelimitedFiles
reshape(readdlm("myfilename.txt"),:,2)


0 commentaires

1
votes

La façon la plus paresseuse de le faire est d'utiliser CSV.jl

using CSV
for row in CSV.File("file.txt",delim=' ',ignorerepeated=true)
  println("a=$(row.a), b=$(row.b), c=$(row.c)")
end

delim = ',': un caractère ou une chaîne qui indique comment les colonnes sont délimitées dans un fichier; si aucun argument n'est fourni, l'analyse essaiera de détecter le délimiteur le plus cohérent sur les 10 premières lignes du fichier


0 commentaires