I have n different length cell vectors, call it c{i}, i=1,2,...,n.
I wanna find those c{i} which equal with others, for example:
c{1}=[1 2 3 4 5 6]; c{2}=[1 3 5 7]; c{3}=[2 4 6 8];
c{4}=[1 4 6]; c{5}=[3 7]; c{6}=[2 4 6 8]; c{7}=[1 3 5 7];
I hope I can find [2 4 6 8] and [1 3 5 7] with a simple way instead of using two loops.
Thanks!
You can do it with unique. You need to convert vectors to strings, because unique works with cell arrays of strings but not with cell arrays of numeric vectors. After unique, you can count how many strings (vector) are repeated with histc, and them some indexing lets you retrieve the corresponding vectors:
strcell = cellfun(#(e) num2str(e), c, 'uniformoutput', 0); %// convert to strings
[~, ii, jj] = unique(strcell); %// apply unique. Second and third outputs needed
ind = find(histc(jj,min(jj)-.5:max(jj)+.2)>1); %// which appear more than once
result = c(ii(ind)); %// indexing to obtain corresponding original vectors
Related
I'm trying to access a part of a multidimensional array in Matlab - it could be done like this: X(2:3, 1:20, 5, 4:7)
However, neither the number of elements, nor the ranges are fixed, so I want to provide the indices from arrays - for the above example they'd be
ind1 = [2 1 5 4];
ind2 = [3 20 5 7];
For a fixed number of dimensions this is not a problem (X(ind1(1):ind2(1),...), but since they are not I'm not sure how to implement this in Matlab. Is there a way? Or should I approach this differently?
Using comma separated lists you can make it a more quick and friendly:
% some test data
ind1 = [2 1 5 4];
ind2 = [3 20 5 7];
X = randi(99,20,20,20,20);
% get all subscripts in column format
vecs = arrayfun(#colon,ind1,ind2,'un',0);
% extract the values
result = X(vecs{:});
There probably is a more elegant way, but this is a difficult problem so here is one solution:
% some test data
ind1 = [2 1 5 4];
ind2 = [3 20 5 7];
X = randi(99,20,20,20,20);
% get all subscripts in column format
vecs = arrayfun(#colon,ind1,ind2,'Uniformoutput',false);
subs = combvec(vecs{:}).';
% manual sub2ind for a matrix where each row contains one subscript
sizeX = size(X);
idx = cumprod([1 sizeX(1:end-1)])*(subs - [zeros(size(subs,1),1) ones(size(subs,1),size(subs,2)-1)]).';
% reshape
result = reshape(X(idx),ind2-ind1+1);
Subscripts to indices conversion based on Gnovices answer in Indexing of unknown dimensional matrix
I have a cell array as shown below:
a = {[1 2 3] [5 3 6] [9 1 3]};
Now I want to remove the 1s from every array in a that contains 1 so that the output is as shown
a = {[2 3] [5 3 6] [9 3]};
I know the indices of arrays in cell array 'a' which contain 1. This can be done using for loop and a temporary variable, but this is taking a lot of time (I want to perform the operation on a cell array of size something like 1x100000. The one above is just for an example)
I want to know if there is any direct method that can do this quickly.
Pretty much anything is going to be slow with that large of a cell array. You could try to do this with cellfun but it's not necessarily guaranteed to be any faster than a for loop.
a = cellfun(#(x)x(x ~= 1), a, 'UniformOutput', false);
% a{1} =
% 2 3
% a{2} =
% 5 3 6
% a{3} =
% 9 3
As already commented by Suever, because you are using a cell array and it is a dynamic container, you don't have a choice but to iterate through each cell if you want to modify the contents. Just to be self-contained, here is the for loop approach to do things:
for ii = 1 : numel(a)
a{ii} = a{ii}(a{ii} ~= 1);
end
This may be faster as it doesn't undergo the overhead of cellfun. The code above accesses the vector in each cell and extracts out those values that are not equal to 1 and overwrites the corresponding cell with this new vector.
Using your example:
a = {[1 2 3] [5 3 6] [9 1 3]};
We get:
>> format compact; celldisp(a)
a{1} =
2 3
a{2} =
5 3 6
a{3} =
9 3
This example shows how to remove data from individual cells, and how to delete entire cells from a cell array. To run the code in this example, create a 3-by-3 cell array:
C = {1, 2, 3; 4, 5, 6; 7, 8, 9};
Delete the contents of a particular cell by assigning an empty array to the cell, using curly braces for content indexing, {}:
C{2,2} = []
This code returns
C =
[1] [2] [3]
[4] [] [6]
[7] [8] [9]
Delete sets of cells using standard array indexing with smooth parentheses, (). For example, this command
C(2,:) = []
removes the second row of C:
`
C =
[1] [2] [3]
[7] [8] [9]`
I know this is simple but am having a hard time finding the right function for this. I have a vector a = [1 2 3 4] and another vector b = [1 2 6 8]. I want to return all of the elements in a that aren't in b. In this case, it would be [3 4]. How do you do this?
did you try with setdiff?
c = setdiff(a,b)
I need to compare two different arrays in Matlab. It's going to be used for a Yahtzee game. If I have an array that contains [1 2 3 4] and an array that contains [1 2 3 4 5], how do I check if the first array is contained within the second array. I just need to know a T/F result, not anything about which elements are missing, etc.
ismember will do it. For example:
x = [1 2 3 4]
y = [1 2 3 4 5]
all(ismember(x,y))
You can also use setdiff. For example:
isempty(setdiff(x,y))
another option,
all(intersect(x,y)==x)
but ismember is probably more efficient....
Suppose, in Matlab, I have the following vectors:
X = [1 2 7 4 5 9 8]
Y = [2 5]
I need the set of indices in X that hold elements greater than the elements in Y. For exmple, the required output here would be,
Z = [3 4 6 7]
I am looking for an efficient way to do this. Any ideas? Thanks in advance.
If you mean that they are greater than all elements in Y,
Z = X>max(Y);
However, if you mean that they are greater than at least one element in Y
Z = X>min(Y);