Julia Array Concatenation dimension mismatch - arrays

I have a dimensional mismatch problem when using y =[x,a] to concatenate my two arrays:
x = reshape(1:16, 4, 4)
x = mean((x ./ mean(x,1)),2)'
a = zeros(3)
println(x)
y =[x,a]
print (y)
If I try combining them I will get this error:
mismatch in dimension 2
Both variables x and a appear to be in the same dimensions in the console:
println(x)
[0.7307313376278893 0.9102437792092966 1.0897562207907034 1.2692686623721108]
println(a)
[0.0,0.0,0.0]
But x is in the second dimension. Is there a way to combine the arrays so I can get in dimension 1?
y = [0.7307313376278893 0.9102437792092966 1.0897562207907034 1.2692686623721108, 0.0,0.0,0.0]

The problem is that by transposing x (putting a ' at the end of the line) you end up with the following:
julia> size(x)
(1,4)
julia> size(a)
(3,)
So when you try y=[x,a] Julia rightfully complains that it cannot concatenate them.
There are (at least) two solutions:
1) Don't transpose x:
x = reshape(1:16, 4, 4)
x = mean((x ./ mean(x,1)),2)
a = zeros(3)
println(x)
y =[x,a]
print (y)
2) also transpose a and concatenate without a comma:
x = reshape(1:16, 4, 4)
x = mean((x ./ mean(x,1)),2)'
a = zeros(3)'
println(x)
y =[x a]
print (y)
In the first case you will have size(y) = (7, 1) and in the second case you will have size(y) = (1,7), so which option you choose will depend on what you want for the size of y.

Related

Indexing 3D arrays with Numpy

I have an array in three dimensions (x, y, z) and an indexing vector. This vector has a size equal to the dimension x of the array. Its objective is to index a specific y bringing their respective z, i.e., the expected result has dimension (x, z).
I wrote a code that works as expected, but does anyone know if a Numpy function can replace the for loop and solve the problem more optimally?
arr = np.random.rand(100,5,2)
result = np.random.rand(100,2)
id = [np.random.randint(0, 5) for _ in range(100)]
for i in range(100):
result[i] = arr[i,id[i]]
You can achieve this with this piece of code:
import numpy as np
arr = np.random.randn(100, 5, 2)
ids = np.random.randint(0, 5, size=100)
res = arr[range(100), ids]
res.shape # (100, 2)

Compact form of python first and second elements of array

I have defined two arrays:
a=np.array([[2,3,4],[5,6,7],[8,9,10]])
b=np.array([-1,-2])
and created a third one:
x=np.asarray([[x - a/2, x + a/2] for x in b])
Now, I have defined two variables
u,v = x[:,0], x[:,1]
My question is extremely simple: is there a way to define those variables without the comma, using only array operations? If I write
u,v = x[:,]
the ordering comes out wrong.
If x is 2D:
u, v = x.T
If x is ND:
u, v = np.swapaxes(x, 0, 1)
To confirm:
>>> np.all(u == x[:, 0])
True
>>> np.all(v == x[:, 1])
True

Python: append kmean.labels_ to Numpy array

The size of two Numpy array are:
(406, 278)
(406,)
however, error occurred while appending Numpy array:
ValueError: all the input arrays must have same number of dimensions
code:
y = numpy.array(kmeans.labels_,copy=True)
x = numpy.append(x, y, axis=1); #error
x = numpy.append(x, y, axis=0); #error
As the error says, you are trying to append a 1d array to a 2d array with an axis parameter, and according to docs:
When axis is specified, values must have the correct shape.
You need to reshape y to a 2d array firstly:
Both of these two methods should work:
np.append(x, y[None, :], axis=0)
np.append(x, y.reshape(1,-1), axis=0)
According to numpy documentation ,
When axis is specified, values must have the correct shape.
So if you want to append the vector y = [0 1 2] to the matrix x = [[0, 0],[1, 1],[2, 2]] with axis=1, first you need to turn y into a matrix form, and then transpose it:
x = numpy.zeros((406,278))
y = numpy.zeros((406,))
x = numpy.append(x, numpy.transpose([y]), axis=1);
print(x.shape) # gives (406,279)

efficient way to remember array index of two large arrays

I have two Fortran arrays in 2 and 3 dimensions, say a(nx,ny) and b(nx,ny,nz). In array a, I need to find out the satisfied points, say values > 0. Then I need to locate the vectors in array b having the same indexes of x and y of those satisfied points in a. What is the easiest and fast way to do it? The two arrays are big, and I don't want to search one element by one element. Hope I explain my problem clearly! thanks!
I'm not sure that this is the best method, but here's what I would do:
Put a where clause inside a do loop over the z-values. You can first get a 2D map of valid indices into a logical array if you don't want to recalculate the points every time:
program indices
implicit none
integer, parameter :: nx = 3000, ny = 400, nz = 500
integer, dimension(nx, ny) :: a
integer, dimension(nx, ny, nz) :: b
logical, dimension(nx, ny) :: valid_points
integer :: x, y, z
do y = 1, ny
do x = 1, nx
a(x, y) = x - y
end do
end do
valid_points = (a > 0)
do z = 1, nz
where(valid_points)
b(:, :, z) = z
else where
b(:, :, z) = 0
end where
end do
end program indices

indexing into an octave array using another array

Hi I have an three dimensional octave array A of size [x y z]
Now I have another array B of dimensions n * 3
say B(0) gives [3 3 1]
I need to access that location in A ie A(3, 3, 1) = say 15
something like A(B(0))
How do I go about it?
See the help for sub2ind (and ind2sub).
However, nowadays people recommend to use loops.
Well, first, B(0) is invalid index, as addressing in MATLAB and Octave begins from 1. Other issue is that you want that B(0) would contain a vector [3 3 1 ]. Matrices in MATLAB can not contain other matrices, only scalars. So you need to use a 3x3 cell array, a 3x3 struct or a 4-dimensional array. I'll choose here the cell array option, because I find it easiest and most convenient.
% Set random seed (used only for example data generation).
rng(123456789);
% Let's generate some pseudo-random example data.
A = rand(3,3,3);
A(:,:,1) =
0.5328 0.7136 0.8839
0.5341 0.2570 0.1549
0.5096 0.7527 0.6705
A(:,:,2) =
0.6434 0.8185 0.2308
0.7236 0.0979 0.0123
0.7487 0.0036 0.3535
A(:,:,3) =
0.1853 0.8994 0.9803
0.7928 0.3154 0.5421
0.6122 0.4067 0.2423
% Generate an example 3x3x3 cell array of indices, filled with pseudo-random 1x3 index vectors.
CellArrayOfIndicesB = cellfun(#(x) randi(3,1,3), num2cell(zeros(3,3,3)), 'UniformOutput', false);
% Example #1. Coordinates (1,2,3).
Dim1 = 1;
Dim2 = 2;
Dim3 = 3;
% The code to get the corresponding value of A directly.
ValueOfA = A(CellArrayOfIndicesB{Dim1,Dim2,Dim3}(1), CellArrayOfIndicesB{Dim1,Dim2,Dim3}(2), CellArrayOfIndicesB{Dim1,Dim2,Dim3}(3));
ValueOfA =
0.8839
% Let's confirm that by first checking where CellArrayOfIndicesB{1,2,3} points to.
CellArrayOfIndicesB{1,2,3}
ans =
[ 1 3 1 ]
% CellArrayOfIndicesB{1,2,3} points to A(1,3,1).
% So let's see what is the value of A(1,3,1).
A(1,3,1)
ans =
0.8839
% Example #2. Coordinates (3,1,2).
Dim1 = 3;
Dim2 = 1;
Dim3 = 2;
ValueOfA = A(CellArrayOfIndicesB{Dim1,Dim2,Dim3}(1), CellArrayOfIndicesB{Dim1,Dim2,Dim3}(2), CellArrayOfIndicesB{Dim1,Dim2,Dim3}(3));
ValueOfA =
0.4067
CellArrayOfIndicesB{3,1,2}
ans =
[ 3 2 3 ]
A(3,2,3)
ans =
0.4067

Resources