convert Array to indicator matrix - arrays

Given the y Array, is there a cleaner or more idiomatic way to create a 2D Array such as Y?
y = [1.0 2.0 3.0 4.0 1.0 2.0]'
Y = ifelse(y .== 1, 1.0, 0.0)
for j in 2:length(unique(y))
Y = hcat(Y, ifelse(y .== j, 1.0, 0.0) )
end
julia> Y
6x4 Array{Float64,2}:
1.0 0.0 0.0 0.0
0.0 1.0 0.0 0.0
0.0 0.0 1.0 0.0
0.0 0.0 0.0 1.0
1.0 0.0 0.0 0.0
0.0 1.0 0.0 0.0

One alternative approach is to use broadcast:
julia> broadcast(.==, y, (1:4)')
6x4 Array{Float64,2}:
1.0 0.0 0.0 0.0
0.0 1.0 0.0 0.0
0.0 0.0 1.0 0.0
0.0 0.0 0.0 1.0
1.0 0.0 0.0 0.0
0.0 1.0 0.0 0.0
(.== broadcasts automatically, so if you just wanted a BitArray you could write y .== (1:4)'.)
This avoids the explicit for loop and also the use of hcat to build the array. However, depending on the size of the array you're looking to create, it might be most efficient to allocate an array of zeros of the appropriate shape and then use indexing to add the ones to the appropriate column on each row.

Array comprehension is an idiomatic and fast way to create matrices in Julia. For the example in the question:
y = convert(Vector{Int64},vec(y)) # make sure indices are integer
Y = [j==y[i] ? 1.0 : 0.0 for i=1:length(y),j=1:length(unique(y))]
What was probably intended was:
Y = [j==y[i] ? 1.0 : 0.0 for i=1:length(y),j=1:maximum(y)]
In both cases Y is:
6x4 Array{Float64,2}:
1.0 0.0 0.0 0.0
0.0 1.0 0.0 0.0
0.0 0.0 1.0 0.0
0.0 0.0 0.0 1.0
1.0 0.0 0.0 0.0
0.0 1.0 0.0 0.0

In numerical analysis, a sparse matrix is a matrix in which most of
the elements are zero.
And from Julia Doc:
sparse(I,J,V,[m,n,combine])
Create a sparse matrix S of dimensions m x n such that S[I[k], J[k]] =
V[k]. The combine function is used to combine duplicates. If m and n
are not specified, they are set to max(I) and max(J) respectively. If
the combine function is not supplied, duplicates are added by default.
y = [1, 2, 3, 4, 1, 2]
rows=length(y);
clms=4 # must be >= maximum(y);
s=sparse(1:rows,y,ones(rows),rows,clms);
full(s) # =>
6x4 Array{Float64,2}:
1.0 0.0 0.0 0.0
0.0 1.0 0.0 0.0
0.0 0.0 1.0 0.0
0.0 0.0 0.0 1.0
1.0 0.0 0.0 0.0
0.0 1.0 0.0 0.0

Related

Is it possible to plot a series of matrices in this format using gnuplot

My code currently creates an output that comes out as so (using example numbers)
0.0 0.0 0.0
0.0 1.0 0.0
0.0 0.0 0.0
0.0 0.0 2.0
0.0 0.0 0.0
0.0 0.0 2.0
0.0 0.0 0.0
1.0 0.0 0.0
0.0 0.0 0.0
0.0 3.0 0.0
0.0 0.0 0.0
0.0 0.0 1.0
3.0 0.0 0.0
0.0 0.0 0.0
1.0 0.0 2.0
0.0 0.0 0.0
3.0 0.0 0.0
0.0 0.0 0.0
1.0 0.0 2.0
0.0 0.0 0.0
3.0 0.0 0.0
0.0 0.0 0.0
1.0 0.0 2.0
0.0 0.0 0.0
3.0 0.0 0.0
0.0 0.0 0.0
1.0 0.0 2.0
0.0 0.0 0.0
was hoping for a solution on how to plot this data either as a 3D splot or as a gif that cycles through each matrix (actual code contains a few hundred matrices). I'm able to alter the output format if necessary. So far I've tried
do for [i=1:7] {
plot "data.txt" matrix with image
}
As well as attempting other solutions I've found on the site but none seem to be trying to do the same thing as me.
If anyone who has gnuplot experience could help me that would be a huge help (I'm using mac if that makes a difference)
Welcome to StackOverflow! I assume all separations of your matrices are two empty lines.
If this is the case you can address the matrices via index (check help index).
You can find out with stats (check help stats) how many blocks you have. Loop through these blocks and set the output to term gif animate (check help gif). Instead of plotting the datablock $Data simply plot your file.
Scrupt:
### plot matrices as asnimation
reset session
$Data <<EOD
0.0 0.0 0.0
0.0 1.0 0.0
0.0 0.0 0.0
0.0 0.0 2.0
0.0 0.0 0.0
0.0 0.0 2.0
0.0 0.0 0.0
1.0 0.0 0.0
0.0 0.0 0.0
0.0 3.0 0.0
0.0 0.0 0.0
0.0 0.0 1.0
3.0 0.0 0.0
0.0 0.0 0.0
1.0 0.0 2.0
0.0 0.0 0.0
3.0 0.0 0.0
0.0 0.0 0.0
1.0 0.0 2.0
0.0 0.0 0.0
3.0 0.0 0.0
0.0 0.0 0.0
1.0 0.0 2.0
0.0 0.0 0.0
EOD
stats $Data u 0 nooutput # get the number of blocks
N = STATS_blocks
set term gif size 600,400 animate delay 30
set output "SO72250259.gif"
set size ratio -1
set cbrange [0:3]
set xrange [-0.5:2.5]
set yrange [-0.5:3.5]
do for [i=0:N-1] {
plot $Data index i matrix w image
}
set output
### end of script
Result:

Place a small array into a big array

I have 2 arrays; one is small array and second is big array as follows,
import pandas as pd
import numpy as np
dat1 = np.array([2, 3 ,4 ,4 ,3 ,2, 2, 4 ,3 ,4 ,4, 3])
dat2 = np.array([1, 4 ,4, 4, 2 ,1, 3 ,3 ,2, 3, 3, 1])
small_array = pd.crosstab(dat1, dat2)
big_array = pd.DataFrame(np.zeros(6*6).reshape(6,6), columns=[1,3,4,2,6,5], index=[3,4,1,2,5,6])
Now I want to place small_array into big_array matching the rownames and colnames between both arrays.
Is there any easy way to perform this?
Any pointer will be very helpful
You can update big_array in-place:
big_array.update(small_array)
print(big_array)
If you want to create a new DataFrame, you can use combine_first:
out = small_array.combine_first(big_array)
Output:
1 3 4 2 6 5
3 1.0 0.0 1.0 2.0 0.0 0.0
4 0.0 3.0 2.0 0.0 0.0 0.0
1 0.0 0.0 0.0 0.0 0.0 0.0
2 2.0 1.0 0.0 0.0 0.0 0.0
5 0.0 0.0 0.0 0.0 0.0 0.0
6 0.0 0.0 0.0 0.0 0.0 0.0
Let us try reindex_like
out = small_array.reindex_like(big_array).fillna(0)
Out[494]:
1 3 4 2 6 5
3 1.0 0.0 1.0 2.0 0.0 0.0
4 0.0 3.0 2.0 0.0 0.0 0.0
1 0.0 0.0 0.0 0.0 0.0 0.0
2 2.0 1.0 0.0 0.0 0.0 0.0
5 0.0 0.0 0.0 0.0 0.0 0.0
6 0.0 0.0 0.0 0.0 0.0 0.0

Why doesn't the following array initialization work in Julia 1.0

I'm trying to plot a bunch of complex contours and attempted the following:
ax_matrix = Array{Union{Int,Float64},2}(length(iters),length(bx));
where iters and bx are 1-dimensional arrays. This gives me to following error:
LoadError: MethodError: no method matching Array{Union{Float64,Int64},2}(::Int64,::Int64)
Closest candidates are:
Array{Union{Float64, Int64},2}(::UndefInitializer, ::Int64, ::Int64) where T at boot.jl:396
Array{Union{Float64, Int64},2}(::UndefInitializer, ::Int64...) where {T, N} at boot.jl:400
Array{Union{Float64, Int64},2}(::UndefInitializer, ::Integer, ::Integer) where T at sysimg.jl:143
Seems like I'm missing and ::UndefInitializer-type parameter, but what is it exactly?
You spell it as undef like this:
julia> Array{Union{Int,Float64},2}(undef, 5, 5)
5×5 Array{Union{Float64, Int64},2}:
0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0
You could also write (but this is verbose thus the fist option was introduced):
julia> Array{Union{Int,Float64},2}(UndefInitializer(), 5, 5)
5×5 Array{Union{Float64, Int64},2}:
0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0

Multiple assignment in multidimensional array

I have a 4x4 array of zeros.
julia> X = zeros(4,4)
4x4 Array{Float64,2}:
0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0
I have an 2xN array containing indices of elements in X that I want to assign a new value.
julia> ind = [1 1; 2 2; 3 3]
3x2 Array{Int64,2}:
1 1
2 2
3 3
What is the simplest way to assign a value to all elements in X whose indices are rows in ind? (something like X[ind] = 2.0).
julia> X
2.0 0.0 0.0 0.0
0.0 2.0 0.0 0.0
0.0 0.0 2.0 0.0
0.0 0.0 0.0 0.0
I'm not sure there is a non-looping way to do this. What's wrong with this?
for i=[1:size(ind)[1]]
a, b = ind[i, :]
X[a, b] = 2.0
end
user3467349's answer is correct, but inefficient, because it allocates an Array for the indices. Also, the notation [a:b] is deprecated as of Julia 0.4. Instead, you can use:
for i = 1:size(ind, 1)
a, b = ind[i, :]
X[a, b] = 2.0
end

Ada - divide a float number and loop over it until it reaches zero

I need help with this simple iteration problem. I am trying to divide...
vhdl
number : Float := 55.0;
loop
number := number / 3.0;
Put (number);
exit when number <= 0.0;
end loop;
I want it to exit at the first 0.0.
i keep getting infinite loop of
18.3 6.1 2.0 0.7 0.2 0.1 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
The first printed 0.0 is not zero, it is some fairly large number in float terms, rounded to one decimal place.
No matter how many times you divide by 3, if your arithmetic is accurate, you will never actually get zero this way, so you would have written an infinite loop.
Now, arithmetic in Ada isn't really THAT accurate but for this specific example it apparently rounds in such a way as to give the same effect. Or, as Simon says, you didn't wait long enough. It's not reliable; chances are that Long_Float or
type Big_Float is digits 18;
package Big_Float_IO is new Float_IO(Num => Big_Float);
use Big_Float_IO;
number : Big_Float := 55.0;
might give different results.
EDIT: On any system employing IEEE P754 floating point arithmetic with a standard-compliant divide instruction, it will eventually exit, unless you have selected a specific optional rounding mode. BUT that still doesn't make it a good way to program!
If your goal is exactly as you described, then re-state it more formally: exit at the first number representing 0.0 when rounded to one decimal place.
That means, any number < 0.05.
So re-write the loop termination as
exit when number < 0.05;
and be happy.
Otherwise, what is it you are REALLY trying to do?
The code you've posted wouldn't compile; there's no standard operation & which takes a String on the left and a Float on the right, and returns a String.
That said, I think you may not have waited long enough: for me, it stops after 99 lines,
...
number= 8.40779E-45
number= 2.80260E-45
number= 1.40130E-45
number= 0.00000E+00
I wonder why your comparison is <=? How could number become negative?

Resources