Concatenating 1D matrices of different sizes - arrays

I perhaps am going about this wrong, but I have data{1}, data{2}...data{i}. Within each, I have .type1, .type2.... .typeN. The arrays are different lengths, so horizontal concatenation does not work.
For simplicity sake
>> data{1}.type1
ans =
1
2
3
>> data{2}.type1
ans =
2
4
5
6
Results should be [1;2;3;2;4;5;6]
I've been trying to loop it but not sure how? I will have a variable number of files (a,b..). How do I go about looping and concatenating? Ultimately I need a 1xN array of all of this..
My working code, thanks..figured it out..
for i = 1:Types
currentType = nTypes{i}
allData.(currentType)=[];
for j = 1:nData
allData.(currentType) = [allData.(currentType); data{j}.(currentType)(:,3)]; %3rd column
end
end

Look at cat, the first argument is the dimension. In your simple example it would be:
result = cat(1,a,b);
Which is equivalent to:
result = [a;b];
Or you can concatenate them as row vectors and transpose back to a column vector:
result = [a',b']';
For the case of a structure inside a cell array I don't think there will be any way around looping. Let's say you have a cell array with M elements and N "types" as the structure fields for each element. You could do:
M=length(data);
newData=struct;
for i=1:M
for j=1:N
field=sprintf('type%d',j); % //field name
if (M==1), newData.(field)=[]; end % //if this is a new field, create it
newData.(field)=[newData.(field);data{i}.(field)];
end
end

Related

Nesting arrays in MATLAB

arr=[ [],[],[] ];
for i=1:3
arr(i)=[i,i+1];
end
Expected output: arr=[[1,2],[2,3],[3,4]];
I am trying to put multiple arrays into a single array and I have tried the above code but it does not work
How can I nest arrays?
What you are trying is very Pythonic, nesting lists in lists. This doesn't work in MATLAB. You have basically two easy options: a multi-dimensional array, or a cell array with arrays.
arr = zeros(3,2); % initialise empty array
arr_cell = cell(3,1); % initialise cell
for ii = 1:3
arr(ii,:) = [ii, ii+1]; % store output as columns
arr_cell{ii} = [ii, ii+1]; % store cells
end
arr =
1 2
2 3
3 4
celldisp(arr_cell)
arr_cell{1} =
1 2
arr_cell{2} =
2 3
arr_cell{3} =
3 4
Cells can take various sized (or even types of) arguments, whereas a multi-dimensional matrix has to have the same number of columns on each row. This makes a cell array more flexible, but the numerical array is a lot faster and has more numerical functions available to it.
A small side-note, I suggest to not use i as a variable name in MATLAB, as it's a built-in function.

Filling a row and columns of a ndarray with a loop

I'm starting with Python and I have a basic question with "for" loop
I have two array which contains a values of a same variables:
A = data_lac[:,0]
In the first array, I have values of area and in the second on, values of mean depth.
I would like to find a way to automatize my calculation with different value of a parameter. The equation is the following one:
g= (np.sqrt(A/pi))/n
Here I can calculte my "g" for each row. Now I want to have a loop with differents values of "n". I did this:
i=0
while i <= len(A)-1:
for n in range(2,6):
g[i] = (np.sqrt(A[i]/pi))/n
i += 1
break
In this case, I just have one column with the calculation for n = 2 but not the following one. I tried to add a second dimension to my array but I have an error message saying that I have too many indices for array.
In other, I would like this array:
g[len(A),5]
g has 5 columns each one calculating with a different "n"
Any tips would be very helpful,
Thanks
Update of the code:
data_lac=np.zeros((106,7))
data_lac[:,0:2]=np.loadtxt("/home...", delimiter=';', skiprows=1, usecols=(0,1))
data_lac[:,1]=data_lac[:,1]*0.001
#Initialisation
A = data_lac[:,0]
#example for A with 4 elements
A=[2.1, 32.0, 4.6, 25]
g = np.zeros((len(A),))
I believe you share the indexes within both loops. You were increasing the i (index for the upper while loop) inside the inner for loop (which index with n).
I guess you have A (1 dim array) and you want to produce G (2 dim array) with size of (Len(A, 5))
I am not sure I'm fully understand your require output but I believe you want something like:
i=0
while i <= len(A)-1:
for n in range(2,6):
g[i][n-2] = (np.sqrt(A[i]/pi))/n # n-2 is to get first index as 0 and last as 4
i += 1 # notice the increace of the i is for the upper while loop
break
Important - remember that in python indentation means a lot -> so make sure the i +=1 is under the while scope and not indent to be inside the for loop
Notice - G definition should be as:
g = np.zeros((len(A),4), dtype=float)
The way you define it (without the 4) cause it to be 1 dim array and not 2-dim

matlab: logically comparing two cell arrays

I have an excel file from which I obtained two string arrays, Titles of dimension 6264x1 and another Names of dimension 45696x1. I want to create an output matrix of size 6264x45696 containing in the elements a 1 or 0, a 1 if Titles contains Names.
I think I want something along the lines of:
for (j in Names)
for (k in Titles)
if (Names[j] is in Titles[k])
write to excel
end
end
end
But I don't know what functions I should use to achieve what I have in the picture. Here is what I have come up with:
[~,Title] = xlsread('exp1.xlsx',1,'A3:A6266','basic');
[~,Name] = xlsread('exp1.xlsx',2,'B3:B45698','basic');
A = cellstr(Title);
GN = cellstr(Name);
BinaryMatrix = false(45696,6264);
for i=1:1:45696
for j=1:1:6264
if (~isempty(ismember(A,GN)))
BinaryMatrix(i,j)= true;
end
end
end
the problem with this code is that it never finishes running, although there are no suggestions within matlab.
You can use third output of unique to get numbers corresponding to each string element and use bsxfun to compare numbers.
GN = cellstr(Name);
A = cellstr(Title);
B = [ GN(:); A(:)];
[~,~,u]= unique(B);
BinaryaMatrix = bsxfun(#eq, u(1:numel(GN)),u(numel(GN)+1:end).');
ismember can handle cell arrays of character vectors. Its second output tells you the information you need, from which you can build the result using sparse (it could also be done by preallocating and using [sub2ind):
[~, m] = ismember(Titles, Names);
BinaryMatrix = full(sparse(nonzeros(m), find(m), true, numel(Names), numel(Titles)));

multidimensional cell array in Matlab

I'v 3 cell arrays of same number of cells, However I want to reduce in only one cell array having multiple dimensions so that they can be access by column wise like array's column. I'm working in Matlab's environment, However I'v tried to do so, but unfortunately I'v found no cell access as column as in matrices. Any Suggestions for handle such case?
My Code:
P = cell(1,10);
Pd = cell(1,10);
Pdd = cell(1,10);
for ii=1:10
P{ii}= [repmat([0 0 0],2,1)];
Pd{ii} = [repmat([1 1 1],2,1)];
Pdd{ii} = [repmat([2 2 2],2,1)];
end
Concatenate the three cell arrays vertically:
Pall = [P; Pd; Pdd]
This gives a 3x10 cell array Pall, such that Pall(1,:) is P, etc.
If you want to avoid creating multiple cell arrays from the beginning: do something similar to this:
for ii=1:10
Pall{1,ii}= [repmat([0 0 0],2,1)];
Pall{2,ii} = [repmat([1 1 1],2,1)];
Pall{3,ii} = [repmat([2 2 2],2,1)];
end
To avoid loops, with the values in your example:
Pall = mat2cell(repmat([repmat([0 0 0],2,1); repmat([1 1 1],2,1); repmat([2 2 2],2,1)],1,10),[2 2 2],3*ones(1,10))

Turning an array in to a matrix in MATLAB

I need to turn a large array into a matrix in the following way: to take the first m entries of the array and make that the 1st row of the matrix.
For example: if I had an array that was 100 entries long, the corresponding matrix would be 10 rows and each row would be 10 entries of the array with the order preserved.
I've tried the following code:
rows = 10
row_length = 10
a = randi(1,100);
x = zeros(rows,row_length)
for i=1:rows
x(i) = a(i:i+row_length)
end
but with no luck. I'm stuck on how to slide the window along by row_length so that i will start from row_length+1 in the second (and subsequent) iterations of the loop.
The best way to do it is to use Matlab's reshape function:
reshape(a,row_length,[]).'
It will reshape by first assigning down the columns which is why I transpose at the end (i.e. .')
However just for the sake of your learning, this is how you could have done it your way:
rows = 10
row_length = 10
a = rand(1,100)
x = zeros(rows,row_length)
for i=1:row_length:rows*row_length %// use two colons here, the number between them is the step size
x(i:i+row_length-1) = a(i:i+row_length-1) %// You need to assign to 10 elements on the left hand side as well!
end

Resources