2017-10-15 1 views
2

Quand je lis dans un fichier csv contenantreadtable() lorsqu'une chaîne se termine par

"numéro", "texte"

1, "row1text \"

2, » row2text »

avec les commandes

using DataFrames 

readtable(filename.csv) 

Je reçois un dataframe avec une seule ligne. Apparemment, le backslash à la fin du texte dans la première rangée est un problème. Est-ce que ce comportement est attendu? Existe-t-il un moyen alternatif d'éviter ce problème?

Comme une note de côté: Ce qui suit fonctionne très bien (par exemple, je reçois deux lignes), mais est évidemment peu pratique pour lire dans les grands fichiers

df = csv""" 

    "number","text" 

    1,"row1text\" 

    2,"row2text" 

    """ 
+0

Le second est inattendu pour moi. La différence est provoquée par IOBuffer (qui échappe) utilisé dans la macro csv_str. Bien que vous aimez ce comportement, c'est probablement bug. – Liso

Répondre

1

Depuis la barre oblique inverse est le caractère d'échappement par défaut, il échappe la citation marquer et salit tout. Une solution serait d'utiliser le package CSV.jl et spécifier un caractère d'échappement:

julia> using CSV 

julia> CSV.read("filename.csv", escapechar = '~') 
2×2 DataFrames.DataFrame 
│ Row │ number │ text  │ 
├─────┼────────┼─────────────┤ 
│ 1 │ 1  │ "row1text\" │ 
│ 2 │ 2  │ "row2text" │ 

Mais vous devez vous assurer que les ~ chars ne s'échappent pas autre chose. Il pourrait y avoir une meilleure façon de faire cela, mais ce serait un hack pour contourner le problème.

Une autre méthode consiste à traiter les données ligne par ligne. Voici un exemple trop compliqué de le faire:

julia> open("filename.csv", "r") do f 
      for (i, line) in enumerate(eachline(f)) 
       if i == 1 
       colnames = map(Symbol, split(line, ',')) 

       global df = DataFrame(String, 0, length(colnames)) 

       rename!(df, 
         Dict([(old_name, new_name) for (old_name, new_name) in zip(names(df), colnames)])) 

       else 
        new_row = map(String, split(replace(line, "\\\"", "\""), ',')) 
        # replace quotes around vales 
        new_row = map(x -> replace(x, "\"", ""), new_row) 
        push!(df, new_row) 
       end 
      end 
     end 

julia> df 
2×2 DataFrames.DataFrame 
│ Row │ "number" │ "text"  │ 
├─────┼──────────┼────────────┤ 
│ 1 │ "1"  │ "row1text" │ 
│ 2 │ "2"  │ "row2text" │ 
+0

Deuxième est hack aussi (IMHO pire) par exemple: 'println (" \ "problème d'antislash échappé \\\\\" ")' ou 'println (" \ "nouvelle ligne \ n problème \" ")' – Liso

+0

il C'est vraiment un hack et pas très bon non plus. Il suffit de le lancer, alors peut-être que quelqu'un peut l'améliorer ou stimuler de nouvelles solutions. – niczky12