Removing elements from a cell array in MATLAB - arrays

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]`

Related

Accessing values in a matrix for a column previous to the first column?

I am trying to access elements of the previous columns than first column.
For example in python if i try to access elements before the first column 0 it will return an empty array.
import numpy as np
x = np.matrix([[ 1, 2, 10],
[ 1, 4, 2],
[ 2, 3, 2],
[ 2, 3, 6]])
a = x[:, 0]
print('\n a is \n', a)
b = x[:, :0]
print('\n b is \n',b)
Output: -->
a is
[[1]
[1]
[2]
[2]]
b is
[]
But julia does not behave in such manner.
My trial in julia:
array = [1 2 3;3 4 5;2 3 4;1 2 3]
a = array[:, 1]
b = array[:, 1-1]
Output :-->
BoundsError: attempt to access 4×3 Array{Int64,2} at index [1:4, 0]
Stacktrace:
[1] throw_boundserror(::Array{Int64,2}, ::Tuple{Base.Slice{Base.OneTo{Int64}},Int64}) at .\abstractarray.jl:541
[2] checkbounds at .\abstractarray.jl:506 [inlined]
[3] _getindex at .\multidimensional.jl:742 [inlined]
[4] getindex(::Array{Int64,2}, ::Function, ::Int64) at .\abstractarray.jl:1060
[5] top-level scope at In[1166]:1
[6] include_string(::Function, ::Module, ::String, ::String) at .\loading.jl:1091
However, to replicate such operation I tried to implement try and catch method and use it over the loop to see what happens when i try accessing different columns. The output is always an empty array.
for i in 1:3
try
b = array[:, :i-1]
catch
b = []
end
println("\b b in $i is $b")
end
Output :--->
b in 1 is Any[]
b in 2 is Any[]
b in 3 is Any[]
May I know how can I access row elements from first_column - 1 to last_column - 1, where first_column - 1 returns an empty array but rest returns data from the matrix.
The answer to my question is provided by #ettersi on julia discourse, I am posting it here for reference. Please follow the link mentioned in the comment to access the discourse page.
ANSWER!
julia> array = [1 2 3;3 4 5;2 3 4;1 2 3]
4×3 Matrix{Int64}:
1 2 3
3 4 5
2 3 4
1 2 3
julia> array[:, 1:0]
4×0 Matrix{Int64}

How to index a Julia array

I am having trouble understanding what seems like an inconsistent behavior in Julia.
X = reshape(1:100, 10, 10)
b = [1 5 9]
X[2, :][b] # returns the correct array
X[2, :][1 5 9] # throws an error
Can someone explain why using the variable b works to index an array but not when I write the index myself?
Since x = X[2,:] is just a vector, we can simplify the example to just talking about indexing behavior on vectors.
x[v] where v is a collection of integers returns the subset of x. Thus x[(1,5,9)], or x[[1,5,9]] is thus using that getindex(x::Vector,i::AbstractArray) dispatch.
Note that x[[1 5 9]] works because v = [1 5 9] makes v a row vector. That's valid syntax, but x[1 5 9] just isn't even valid Julia syntax. That syntax means something else:
v = Float64[1 5 9]
returns a row vector with element type Float64.
I have figured out a solution.
Rather than write X[2, :][1 5 9] I should have written x[2, :][[1 5 9]]
I believe this makes sense when we imagine indexing on two dimensions the second time. This makes it possible to write more complicate indices, like X[2:4, :][[1 3],[1 3]]

Matlab - Accessing a part of a multidimensional array

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

How to find repeated cell vectors in matlab?

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

Comparing different sized arrays in Matlab

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....

Resources