How to read each line from a file then store the values to array elements?

Sorry for another stupid question. I have a file called Yji.txt, contents is listed below,

  3.29107948   3.01222513   1.81928273   1.73277408   1.01205782
  3.79643512   3.12969360   2.72422926   1.99088313   1.37971501
  2.20058980   2.03869455   2.01194312   1.25660107   0.85350759
  3.27627114   2.36889134   2.07543404   1.40830475   0.84922031
  3.06670541   2.77976809   1.96303171   1.71966277   1.26711606
  3.52942983   2.42193693   2.05404920   1.48999137   0.83146491
  3.37109577   2.41969083   2.02905938   1.50383911   0.74416147
  4.34400391   3.91427909   3.71031537   2.20110125   1.78240591
  3.39792241   2.30627896   2.24137999   1.52784113   0.85893251
  2.63109783   2.38360933   1.92420508   1.17364141   0.73957600

It is 10 lines, each line have 5 elements which are all Float64.
Each of the line, the Float64 numbers are generated by Fortran or Matlab with the format,

5(f12.8,1x)

means (f12.8,1x) is repeated 5 times.
Each of the f12.8,1x means that, the values took 12 space, and 8 of them are occupied by digits, as you can see, they all have 8 digits. The 1x means the values are separated by an additional space.
Anyway, those values are in a txt file called Yji.txt. I am sure Julia is smart enough to read the format automatically.

Now, I want to do the following,
I have an array a=Array{Float64,2}(undef,10,5) ,
a[i,:] should store the 5 values at line i.

a = Array{Float64,2}(undef,10,5)   
for ln in eachline("Yji.txt")
 I need i to represent line number
    a[ i, : ] =  I need to convert ln to the corresponding 5 Float64 numbers, so that they can be stored to a[i,:]
end

How to do that?

I read the β€˜eachline’, and β€˜read’ in Julia document, and googled a little though did not google very hard, but still not very clear, could anyone give some hints?

Sorry for the stupid question.

Thank you very much in advance!

The easiest way is to use the DelimitedFiles module from the standard library.

String to number conversion is done via parse(T, str) where T is the desired numeric type, and split(str) splits a string at whitespaces. Those are useful when your input is more noisy and cannot be handled by the standard tools for reading tables.

2 Likes

Probably easiest to do using DelimitedFiles; readdlm("myfile.txt")

1 Like

You can use either the DelimitedFiles stdlib:

julia> using DelimitedFiles, CSV, DataFrames                    
                                                                
julia> dlm = readdlm("tmp.txt")                                 
10Γ—5 Matrix{Float64}:                                           
 3.29108  3.01223  1.81928  1.73277  1.01206                    
 3.79644  3.12969  2.72423  1.99088  1.37972                    
 2.20059  2.03869  2.01194  1.2566   0.853508                   
 3.27627  2.36889  2.07543  1.4083   0.84922                    
 3.06671  2.77977  1.96303  1.71966  1.26712                    
 3.52943  2.42194  2.05405  1.48999  0.831465                   
 3.3711   2.41969  2.02906  1.50384  0.744161                   
 4.344    3.91428  3.71032  2.2011   1.78241                    
 3.39792  2.30628  2.24138  1.52784  0.858933                   
 2.6311   2.38361  1.92421  1.17364  0.739576                   

Or you can use CSV.jl and DataFrames.jl (which will be helpful in the future, since a lot of other packages use DataFrames as well):

julia> CSV.read("tmp.txt", DataFrame, header=0, delim="   ")    
10Γ—5 DataFrame                                                  
 Row β”‚ Column1     Column2     Column3     Column4     Column5  
     β”‚ String      String      String      String      Float64  
─────┼──────────────────────────────────────────────────────────
   1 β”‚ 3.29107948  3.01222513  1.81928273  1.73277408  1.01206  
   2 β”‚ 3.79643512  3.12969360  2.72422926  1.99088313  1.37972  
   3 β”‚ 2.20058980  2.03869455  2.01194312  1.25660107  0.853508 
   4 β”‚ 3.27627114  2.36889134  2.07543404  1.40830475  0.84922  
   5 β”‚ 3.06670541  2.77976809  1.96303171  1.71966277  1.26712  
   6 β”‚ 3.52942983  2.42193693  2.05404920  1.48999137  0.831465 
   7 β”‚ 3.37109577  2.41969083  2.02905938  1.50383911  0.744161 
   8 β”‚ 4.34400391  3.91427909  3.71031537  2.20110125  1.78241  
   9 β”‚ 3.39792241  2.30627896  2.24137999  1.52784113  0.858933 
  10 β”‚ 2.63109783  2.38360933  1.92420508  1.17364141  0.739576 

(The parsed numbers are the same, they’re just printed/displayed to a different precision.)


Just noticed that the autodetection of Float64 columns seems to have failed here, you can just create a DataFrame from the matrix given by readdlm as well:

julia> DataFrame(dlm, :auto)                        
10Γ—5 DataFrame                                      
 Row β”‚ x1       x2       x3       x4       x5       
     β”‚ Float64  Float64  Float64  Float64  Float64  
─────┼──────────────────────────────────────────────
   1 β”‚ 3.29108  3.01223  1.81928  1.73277  1.01206  
   2 β”‚ 3.79644  3.12969  2.72423  1.99088  1.37972  
   3 β”‚ 2.20059  2.03869  2.01194  1.2566   0.853508 
   4 β”‚ 3.27627  2.36889  2.07543  1.4083   0.84922  
   5 β”‚ 3.06671  2.77977  1.96303  1.71966  1.26712  
   6 β”‚ 3.52943  2.42194  2.05405  1.48999  0.831465 
   7 β”‚ 3.3711   2.41969  2.02906  1.50384  0.744161 
   8 β”‚ 4.344    3.91428  3.71032  2.2011   1.78241  
   9 β”‚ 3.39792  2.30628  2.24138  1.52784  0.858933 
  10 β”‚ 2.6311   2.38361  1.92421  1.17364  0.739576 
2 Likes

Thank you all very much @nilshg , @Vasily_Pisarev @Sukera .
Nice, now I know I can do

using DelimitedFiles
a = readdlm("Yji.txt",Float64)

or just a = readdlm(β€œYji.txt”)

However, it seems the values in the array a are all truncated to 6 digits or less,

 3.29108  3.01223  1.81928  1.73277  1.01206
 3.79644  3.12969  2.72423  1.99088  1.37972
 2.20059  2.03869  2.01194  1.2566   0.853508
 3.27627  2.36889  2.07543  1.4083   0.84922
 3.06671  2.77977  1.96303  1.71966  1.26712
 3.52943  2.42194  2.05405  1.48999  0.831465
 3.3711   2.41969  2.02906  1.50384  0.744161
 4.344    3.91428  3.71032  2.2011   1.78241
 3.39792  2.30628  2.24138  1.52784  0.858933
 2.6311   2.38361  1.92421  1.17364  0.739576

but originally they have 8 digits.
Is there a way to keep all the digits from the original values?
Or is it that they are not really β€˜truncated’, and just displayed as less digits?

It’s just a display thing:

julia> dlm = readdlm("tmp.txt", Float64)     
10Γ—5 Matrix{Float64}:                        
 3.29108  3.01223  1.81928  1.73277  1.01206 
 3.79644  3.12969  2.72423  1.99088  1.37972 
 2.20059  2.03869  2.01194  1.2566   0.853508
 3.27627  2.36889  2.07543  1.4083   0.84922 
 3.06671  2.77977  1.96303  1.71966  1.26712 
 3.52943  2.42194  2.05405  1.48999  0.831465
 3.3711   2.41969  2.02906  1.50384  0.744161
 4.344    3.91428  3.71032  2.2011   1.78241 
 3.39792  2.30628  2.24138  1.52784  0.858933
 2.6311   2.38361  1.92421  1.17364  0.739576
                                             
julia> dlm[10,1]                             
2.63109783                                   

julia> show(IOContext(stdout, :compact=>false), MIME"text/plain"(), dlm
10Γ—5 Array{Float64, 2}:                                                
 3.29107948  3.01222513  1.81928273  1.73277408  1.01205782            
 3.79643512  3.1296936   2.72422926  1.99088313  1.37971501            
 2.2005898   2.03869455  2.01194312  1.25660107  0.85350759            
 3.27627114  2.36889134  2.07543404  1.40830475  0.84922031            
 3.06670541  2.77976809  1.96303171  1.71966277  1.26711606            
 3.52942983  2.42193693  2.0540492   1.48999137  0.83146491            
 3.37109577  2.41969083  2.02905938  1.50383911  0.74416147            
 4.34400391  3.91427909  3.71031537  2.20110125  1.78240591            
 3.39792241  2.30627896  2.24137999  1.52784113  0.85893251            
 2.63109783  2.38360933  1.92420508  1.17364141  0.739576              
4 Likes