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
3 Réponses :
(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
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.
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)
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