This is probably a super simple question, but here it is:
I have a <1xn> array of structs, and a vector of the indexes of the struct array that I want to remove.
So for example, if I have a removal vector of [2 6], it means I want to get rid of the 2nd and 6th struct in the array (and the array would be 2 elements shorter).
What is the clean, simple, matlab way of doing this?
If the name of your structure is a:
a([2 6])=[]
or more generally:
ind2rm=[2 6];
a(ind2rm)= []
PS: it also works for normal arrays or matrices (e.g. A(:,[2 6])=[])
I think this is what you need:
a = a(setdiff([1:n], [2, 6]))
a is the struct array and [2, 6] are the elements you want to remove.
Related
I'm writing a MATLAB function to read out data into an n-dimensional array (variable dimension size). I need to be able to access a specific point in the Matrix (to write to it or read it, for example), but I don't know ahead of time how many indexes to specify.
Currently I have a current_point vector which I iterate through to specify each index, and a max_points vector which specifies the size of the array. So, if for example I wanted a 3-dimensional array of size 1000-by-15-by-3, max_points = [1000 15 3], and current_point iterates from [1, 1, 1] to [1000, 15, 3] ([1, 1, 1] -> [1000, 1, 1] -> [1, 2, 1] -> [1000, 2, 1] ->...). What I'd like to be able to do is feed current_point as an index to the matrix like so:
output_matrix(current_point) = val
But apparently something like output_matrix([1 2 3]) = val will just set outputmatrix(1:3) = 30. I can't just use dummy variables because sometimes the matrix will need 3 indexes, other times 4, other times 2, etc, so a vector of variable length is really what I need here. Is there a simple way to use a vector as the points in an index?
Using the function sub2ind to create a linear index is the typical solution to this problem, as shown in this closely-related question. You could also compute a linear index yourself instead of calling sub2ind.
However, your case may be simpler than those in the other questions I linked to. If you're only ever indexing a single point with your current_point vector (i.e. it's just an n-element vector of subscripts into your n-dimensional matrix), then you can use a simple solution where you convert current_point to a cell array of subscripts using the function num2cell and use it to create a comma-separated list of indices. For example:
current_point = [1 2 3 ...]; % A 1-by-n array of subscripts
subCell = num2cell(current_point); % A 1-by-n cell array of subscripts
output_matrix(subCell{:}) = val; % Update the matrix point
The operation subCell{:} creates the equivalent of typing subCell{1}, subCell{2}, ..., which is the equivalent of typing current_point(1), current_point(2), ....
I know it is too late but for anybody who will find this topic. the easiest way that work for me is to use: diag(A (x(:),y(:)) );
unfortunately this works only if you need to get values from the matrix, not for changing values
You can use the sub2ind function to get the linear index from the subscript.
Example:
A=magic(4)
A =
16 2 3 13
5 11 10 8
9 7 6 12
4 14 15 1
selectElement={2,3}; %# get the element at position 2,3 in A.
indx=sub2ind(size(A),selectElement{:});
A(indx)
ans =
10
In the above example, I've stored the subscripts (can be any number of dimensions) as a cell. If you have it stored as a vector, simply use num2cell() to convert it to a cell.
You can now easily assign a value to this as A(indx)=value;. I've used different variables than yours to keep the answer general, but the idea is the same and you just need to replace the variable names.
You also mentioned in your post that you're looping from (1,1,1) till some value, (1000,15,3) and assigning a value to each of these points. If you're looping along the columns, you can replace this entire operation with a vectorized solution.
Let finalElement={1000,15,3} be the final step of the loop. As before, find the linear index as
index=sub2ind(size(A),finalElement{:});
Now if you have the values you assign in the loop stored as a single vector, values, you can simply assign it in a single step as
A(1:index)=values;
Think I have an array like
A = { 1,2,3,4,5,6}
I need to get the position of 4 in this array.
I tried,
p = find(A==4)
Please help.
If you really need a cell array (for example because the cells can contain vectors of different sizes):
A = {1, [1 2 3], 4, [1 2], [3 4]}; %// example cell array
sought = [1 2]; %// sought contents
index = find(cellfun(#(x) isequal(x, sought), A));
you created a cell-array instead of a normal vector.
Try:
A = [1,2,3,4,5,6]
find(A==4)
Cell arrays are great to store variables with different types.You could, for example, create a cell array that contains strings as well as digits.
If you have only digits in your array you should defintely use normal arrays.
These are defined by [ ] instead of { }
As you have defined a cell array you need to convert it to a numeric array for find to work, fortunately this is simple to achieve with a couple of well placed brackets.
A = { 1,2,4,3,5,6};
find([A{:}]==4)
ans =
3
So A{:} writes out the numeric values from your array and the [] contains the output for find to work.
p.s. I re-arranged the numbers in A to show that it was working as '4' is now in position 3 to provide a better test.
I built a cell array that contains non-string elements, say, vectors containing numbers.
How can I search if a vector exits in this cell array? Since the elements are not strings, I cannot use ismember() function.
Concretely, if I had a cell array like
a = {[1 2], [2 3], [3 4], [4 5]}
how can I find out if [2 3] is in this cell array?
I think this should work:
find(ismember(cell2mat(a'),[2 3],'rows'));
or if you don't need the location:
any(ismember(cell2mat(a'),[2 3],'rows'));
Good luck =)
You can try this :
ismember(num2str([2 3]), cellfun(#num2str, a, 'UniformOutput', false))
I'm writing a MATLAB function to read out data into an n-dimensional array (variable dimension size). I need to be able to access a specific point in the Matrix (to write to it or read it, for example), but I don't know ahead of time how many indexes to specify.
Currently I have a current_point vector which I iterate through to specify each index, and a max_points vector which specifies the size of the array. So, if for example I wanted a 3-dimensional array of size 1000-by-15-by-3, max_points = [1000 15 3], and current_point iterates from [1, 1, 1] to [1000, 15, 3] ([1, 1, 1] -> [1000, 1, 1] -> [1, 2, 1] -> [1000, 2, 1] ->...). What I'd like to be able to do is feed current_point as an index to the matrix like so:
output_matrix(current_point) = val
But apparently something like output_matrix([1 2 3]) = val will just set outputmatrix(1:3) = 30. I can't just use dummy variables because sometimes the matrix will need 3 indexes, other times 4, other times 2, etc, so a vector of variable length is really what I need here. Is there a simple way to use a vector as the points in an index?
Using the function sub2ind to create a linear index is the typical solution to this problem, as shown in this closely-related question. You could also compute a linear index yourself instead of calling sub2ind.
However, your case may be simpler than those in the other questions I linked to. If you're only ever indexing a single point with your current_point vector (i.e. it's just an n-element vector of subscripts into your n-dimensional matrix), then you can use a simple solution where you convert current_point to a cell array of subscripts using the function num2cell and use it to create a comma-separated list of indices. For example:
current_point = [1 2 3 ...]; % A 1-by-n array of subscripts
subCell = num2cell(current_point); % A 1-by-n cell array of subscripts
output_matrix(subCell{:}) = val; % Update the matrix point
The operation subCell{:} creates the equivalent of typing subCell{1}, subCell{2}, ..., which is the equivalent of typing current_point(1), current_point(2), ....
I know it is too late but for anybody who will find this topic. the easiest way that work for me is to use: diag(A (x(:),y(:)) );
unfortunately this works only if you need to get values from the matrix, not for changing values
You can use the sub2ind function to get the linear index from the subscript.
Example:
A=magic(4)
A =
16 2 3 13
5 11 10 8
9 7 6 12
4 14 15 1
selectElement={2,3}; %# get the element at position 2,3 in A.
indx=sub2ind(size(A),selectElement{:});
A(indx)
ans =
10
In the above example, I've stored the subscripts (can be any number of dimensions) as a cell. If you have it stored as a vector, simply use num2cell() to convert it to a cell.
You can now easily assign a value to this as A(indx)=value;. I've used different variables than yours to keep the answer general, but the idea is the same and you just need to replace the variable names.
You also mentioned in your post that you're looping from (1,1,1) till some value, (1000,15,3) and assigning a value to each of these points. If you're looping along the columns, you can replace this entire operation with a vectorized solution.
Let finalElement={1000,15,3} be the final step of the loop. As before, find the linear index as
index=sub2ind(size(A),finalElement{:});
Now if you have the values you assign in the loop stored as a single vector, values, you can simply assign it in a single step as
A(1:index)=values;
I would like to sort elements in a comma-separated list. The elements in the list are structs and I would like the list to be sorted according to one of the fields in the struct.
For example, given the following code:
L = {struct('obs', [1 2 3 4], 'n', 4), struct('obs', [6 7 5 3], 'n', 2)};
I would want to have a way to sort L by the field 'n'. Matlab's sort function only works on matrices or arrays and on lists of strings (not even lists of numbers).
Any ideas on how that may be achieved?
Thanks,
Micha
I suggest you do this in three steps: Extract 'n' into an array, sort the array and consequently reorder the elements of the cell array.
%# get the n's
nList = cellfun(#(x)x.n,L);
%# sort the n's and capture the reordering in sortIdx
[sortedN,sortIdx] = sort(nList);
%# use the sortIdx to sort L
sortedL = L(sortIdx)
This is a bit of an aside, but if all of the structures in your cell array L have the same fields (obs and n in this case), then it would make more sense to store L as a 1-by-N structure array instead of a 1-by-N cell array of 1-by-1 structures.
To convert the 1-by-N cell array of structures to a 1-by-N structure array, you can do the following:
L = [L{:}];
Or, you can create the structure array directly using one call to STRUCT instead of creating the cell array of structures as you did in your example:
L = struct('obs',{[1 2 3 4],[6 7 5 3]},'n',{4,2});
Now the solution from Jonas becomes even simpler:
[junk,sortIndex] = sort([L.n]); %# Collect field n into an array and sort it
sortedL = L(sortIndex); %# Apply the sort to L
For what it's worth, here is the solution in Python:
L = [{'n': 4, 'obs': [1, 2, 3, 4]}, {'n': 2, 'obs': [6, 7, 5, 3]}]
L.sort(lambda a,b: a['n'].__cmp__(b['n']))
# L is now sorted as you wanted