Read an Array of Arrays separated by blank lines in Julia - arrays

I have an array of arrays stored as blocks of tabular data in a textfile. The blocks have different number of rows but the same number of columns. Like this:
7 9
9 9
7 1
1 1
3 3
4 1
And so on.
I would like to read them in Julia and to end with an array of arrays, or an array of 2 dimensional arrays, like this:
a=[ [7, 9; 9 ,9], [7, 1; 1, 1 ; 3 3 ]] ...
I am trying with different ideas with do syntax, but I am being not very succesfull yet.
aux=[]
open("cell.dat") do f
aux=[]
aux2=[]
for line in eachline(f)
if line != ""
aux2=vcat(aux2,line)
else
print("tuabuela")
aux=vcat(aux,aux2)
print(aux, aux2)
aux2=[]
end
end
end
I end with an empty array!

There are many ways to do it. Suppose the file is not huge and you have read your file to String called dat:
dat="""7 9
9 9
7 1
1 1
3 3
4 1"""
In that case you can do:
julia> readdlm.(IOBuffer.(split(dat,"\n\n")))
3-element Vector{Matrix{Float64}}:
[7.0 9.0; 9.0 9.0]
[7.0 1.0; 1.0 1.0; 3.0 3.0]
[4.0 1.0]

Related

Pandas How to Align Two Columns in a DataFrame and NaN empty cells

I'm using Python 3.8.8
I have a DataFrame structured like this:
A
B
0
1
1
2
2
1
3
7
4
7
5
8
and an array:
C = [3, 4, 7]
I would like to add an array "C" as a new column to the DataFrame. The problem is this array has a different length of index than the df. I would like to make up for the difference in length in C by filling the empty cells with NaNs. My desired result would look something like:
A
B
C
0
1
NaN
1
2
NaN
2
1
3
3
7
4
4
7
7
5
8
NaN
What I am looking for specifically is a way to add C starting at a specific index of the df, but I don't know how to work around the discrepancy between the length of the df and array.
Thank you for your time
To get around the problem of 'different length' when putting your list into the dataframe, you can convert it to a pandas series. Once you do that, you can easily add it to your dataframe with the rest of the values being filled with np.nan.
In your case, you can specifically also set the index when you convert your C list to a series, which you can then assign to your dataframe. Pandas nature to align data on indices will place the series on the right index
Consider using the code below:
c = pd.Series([3, 4, 7],index=[2,3,4])
df['C'] = c
prints:
A B 0
0 0 1 NaN
1 1 2 NaN
2 2 1 3.0
3 3 7 4.0
4 4 7 7.0
5 5 8 NaN
Renaming 0 should be trivial.

How to implement a decrementing for loop in Julia?

I know that in python I can do something as follows.
for i in range(10, 0, -1):
print(i)
Which will output:
10
9
8
7
6
5
4
3
2
1
I'm very much new to julia and I know I can create normal loops as follows.
for i=1:10
println(i)
end
Intuitively, I tried something like as follows (since I thought it behaved similar to python's range([start], stop[, step]) function).
for i=10:1:-1
println(i)
end
Although it didn't fail, it didn't print anything either. What am I doing wrong?
Is there an intuitive way to loop backwards in julia?
Try this:
julia> for i=10:-1:1
println(i)
end
10
9
8
7
6
5
4
3
2
1
or this
julia> for i=reverse(1:10)
println(i)
end
10
9
8
7
6
5
4
3
2
1
As #phipsgabler noted you can also use:
julia> range(10, 1, step=-1)
10:-1:1
to get the same result again (note though that you have to use 1 as a second index).
From my practice range is usually more useful with with length keyword argument:
julia> range(10, 1, length=10)
10.0:-1.0:1.0
(notice that in this case you get a vector of Float64 not Int)

Manipulating matrix demension

I am trying to put values from one array to another in a certain order. However they are placed in the array in the same dimension as the original.
nodeState = [2 8 5; 1 6 4; 9 0 5];
cState = [];
cState = [nodeState(1,1) nodeState(1,2) nodeState(1,3)
nodeState(2,3) nodeState(3,3) nodeState(3,2)
nodeState(3,1) nodeState(2,1) nodeState(2,2)];
What I am expecting is for my cState to be of this demension
2 8 5 4 5 0 9 1 6
instead of this demension
2 8 5
4 5 0
9 1 6
What do I need to do?
If you split a declaration into multiple lines you must use ... otherwise Matlab interprets the Carriage returns as a new row, so it will create a matrix instead of a vector.
Just do:
cState = [nodeState(1,1) nodeState(1,2) nodeState(1,3) ...
nodeState(2,3) nodeState(3,3) nodeState(3,2) ...
nodeState(3,1) nodeState(2,1) nodeState(2,2)];

"Logical Indexing with a Smaller Array" in matlab [duplicate]

This question already has an answer here:
Linear indexing, logical indexing, and all that
(1 answer)
Closed 7 years ago.
The matlab help page for matrix indexing says:
Logical Indexing with a Smaller Array
In most cases, the logical indexing array should have the same number
of elements as the array being indexed into, but this is not a
requirement. The indexing array may have smaller (but not larger)
dimensions:
A = [1 2 3;4 5 6;7 8 9]
A =
1 2 3
4 5 6
7 8 9
B = logical([0 1 0; 1 0 1])
B =
0 1 0
1 0 1
isequal(numel(A), numel(B))
ans =
0
A(B)
ans =
4
7
8
What kind of crazy rule is matlab using here?
To understand this behavior, it's necessary to understand how matrices are stored in memory. Matlab stores matrices using column major layout. This means the 2d matrix:
A = 1 2 3
4 5 6
7 8 9
is stored in memory as one dimensional array going down the columns of A:
A = { array = [1 4 7 2 5 8 3 6 9]
n_rows = 3
n_cols = 3 }
The matrix B:
B = 0 1 0
1 0 1
is stored in memory as:
B = { array = [0 1 1 0 0 1]
n_rows = 2
n_cols = 3 }
Let's put the underlying representations next to eachother:
A.array = [1 4 7 2 5 8 3 6 9]
B.array = [0 1 1 0 0 1]
Using logical indexing, A(B) gives you [4, 7, 8] If you think a bit deeper, what's causing the unintuitive result is the combination of: (1) Matlab uses column major layout and (2) the number of columns in A and B are different.
Note: I'm using pseudo code here. A.array isn't valid code etc...
Bonus:
You can see what happens when the reshape command is called. The underlying data array doesn't change, just the n_rows and n_cols associated with the data array.

read into arrays in Julia

I'm relatively new to Julia and am looking for an efficient way to read in from a text file and store each "column" in an array (I have 2 columns, but a general solution would be great as well). For instance, I'd like the input
1 2
3 4
5 6
to be read into two arrays, say, x and y, such that x=[1 3 5] and y=[2 4 6]. I have a working solution (might not compile, just free-handed it), but I feel like there is a more efficient way to do this than to hcat and to read the input file line by line. Any suggestions are much appreciated!
Currently, I am doing the following, more or less:
x=[];
y=[];
f=open("filename");
f=readlines(f);
for str in f
s1, s2= split(str, " ");
s1=int(s1);
s2=int(s2);
x=hcat(x, s1);
y=hcat(y, s2);
end
Here's a way.
julia> myarray=int(open(readdlm,"mynums.txt"))
3x2 Array{Int32,2}:
1 2
3 4
5 6
julia> x=myarray[:,1]
3-element Array{Int32,1}:
1
3
5
julia> y=myarray[:,2]
3-element Array{Int32,1}:
2
4
6

Resources