I have a cell array containing 5 1x2 arrays. Is there any way to find the most repeated element? I think I cannot use the "mode" function. I looked it up on the internet and could not find a solution about the problem. Everybody keeps talking about cells array with strings.
The cell array I'm using is like this:
{[1 2], [2 5], [3 4], [1 2], [0 4]}
I would like MATLAB to find [1 2] as the most repeated element.
Thank you in advance.
For uniformly structured cell array (2 elements per cell) case
%// Convert the uniformly structured data to a 2D numeric array
Anum = vertcat(A{:})
%// ID unique rows and ID all rows based on those
[~,unqID,ID ] = unique(Anum,'rows')
%// Use 'mode' on ID and then index into unqID to get the index of
%// the most frequently occurring cell and finally index into the
%// input cell array with that index to get the desired output
out = A{unqID(mode(ID))}
Thus, for the given input data -
A = {[1 2], [2 5], [3 4], [1 2], [0 4]}
You would have -
out =
1 2
More generic case with cells of row vectors
If you are dealing with a cell array that has arbitrary sized row vectors in each cell, you can use this technique -
%// Get all elements of A
A_ele = [A{:}]
%// Get lengths of each cell
lens = cellfun('length',A)
%// Setup a 2D numeric array corresponding to the input cell array
A_num = zeros(max(lens),numel(lens))+max(A_ele)+1
A_num(bsxfun(#ge,lens,[1:max(lens)]')) = A_ele %//'
%// ID each row, find the mode with those & finally have the desired output
[unqrows,unqID,ID ] = unique(A_num.','rows') %//'
out = A{unqID(mode(ID))}
Thus, if you have input as -
A = {[1 2], [2 5], [3 4], [1 2], [0 4], [1 2 1],[9],[7 2 6 3]}
The output would still be -
out =
1 2
This works for a general cell array A:
A = {[4 2] [2 5] [4 2] [1 2 1] [9] [7 2 6 3] [1 2 1] [1 2 1] [7 9]}; %// example data
[ii, jj] = ndgrid(1:numel(A)); %// ii, jj describe all pairs of elements from A
comp = cellfun(#isequal, A(ii), A(jj)); %// test each pair for equality
[~, ind] = max(sum(comp,1)); %// get index of (first) most repeated element
result = A{ii(ind)}; %// index into A to get result
Related
If I have a square and symmetric matrix, for example,
[[0 3 2]
[3 8 4]
[2 4 5]]
I do not want to shuffle rows only or columns only. instead,
how can I, for example (not the following in the strict order as written, but instead at random):
shuffle the matrix in numpy so that row and column 1 are moved together to row and column 3,
while row and column 3 are moved to row and column 2
and row and column 2 are moved to row and column 1
What you are asking for can be done with so-called matrix conjugation:
perm_mat = np.random.permutation(np.eye(len(a),dtype=np.int))
out = (perm_mat # a) # (np.linalg.inv(perm_mat))
Output (random of course):
array([[8., 4., 3.],
[4., 5., 2.],
[3., 2., 0.]])
Or can be done with slicing:
np.random.seed(1)
orders = np.random.permutation(np.arange(len(a)))
a[orders][:,orders]
Output:
array([[0, 2, 3],
[2, 5, 4],
[3, 4, 8]])
I need to sort it by first row 1, row 2 & row 3 in ascending order using np.array list
*Input*
[[9, 3, 2], [4, 0, 1], [5, 8, 6]]
*Expected output*
[[4 0 1]
[5 8 6]
[9 3 2]]
Using the below logics gets partially correct
array_test = np.array(input_list)
array_res=np.sort(input_list, axis=0)
Please correct my logics
I need to sort it by first row 1, row 2 & row 3 in ascending order using
np.array list
Ascending order by entire full row wise 401, 586, 932 should be appears
using numpy-array sort
I'm getting a surprising result when selecting a 2D sub-slice of a slice.
Consider the following 2D int array
a := [][]int{
{0, 1, 2, 3},
{1, 2, 3, 4},
{2, 3, 4, 5},
{3, 4, 5, 6},
}
To select the top left 3x3 2D slice using ranges I would use
b := a[0:2][0:2]
I would expect the result to be
[[0 1 2] [1 2 3] [2 3 4]]
however the second index range doesn't seem to have any effect, and returns the following instead:
[[0 1 2 3] [1 2 3 4] [2 3 4 5]]
What am I missing? Can you simply not select a sub-slice like this where the dimension > 1 ?
You can't do what you want in a single step. Slices and arrays are not 2-dimensional, they are just composed to form a multi-dimensional object. See How is two dimensional array's memory representation
So with a slice expression, you just get a slice that will hold a subset of the "full" rows, and its type will be the same: [][]int. If you slice it again, you just slicing the slice of rows again.
Also note that the higher index in a slice expression is exclusive, so a[0:2] will only have 2 rows, so you should use a[0:3] or simply a[:3] instead.
To get what you want, you have to slice the rows individually like this:
b := a[0:3]
for i := range b {
b[i] = b[i][0:3]
}
fmt.Println(b)
This will output (try it on the Go Playground):
[[0 1 2] [1 2 3] [2 3 4]]
Or shorter:
b := a[:3]
for i, bi := range b {
b[i] = bi[:3]
}
I need to copy a part of a 3D array.
I have the indexes of start and end of the copy.
For example 2D array:
[[2 2 3 4 5]
[2 3 3 4 5]
[2 3 4 4 5]
[2 3 4 5 5]
[2 3 4 5 6]]
starting index, end index are:
mini = [2, 1]
maxi = [4, 3]
So the result should be:
[[3 4 4]
[3 4 5]]
I can write:
result = matrix[mini[0]:maxi[0], mini[1]:maxi[1]]
Is there a way to do it generally ? for 3Dim or NDim arrays ?
The trick here is realizing what the indexing syntax is under the hood. This:
result = matrix[mini[0]:maxi[0], mini[1]:maxi[1]]
Is shorthand in python (not just numpy) for:
indices = slice(mini[0], maxi[0]), slice(mini[1], maxi[1])
result = matrix[indices]
So we just need to generate indices dynamically:
lower = [2, 1, ...]
upper = [4, 3, ...]
indices = tuple(np.s_[l:u] for l, u in zip(lower, upper))
result = matrix_nd[indices]
np.s_[a:b] is a shorthand for slice(a, b). Here we build a tuple containing as many slices as you have values in lower and upper
What you are looking for is the slice object, see that example:
matrix = np.random.rand(4,5)
mini = [2, 1]
maxi = [4, 3]
slices=[slice(b,e) for b, e in zip(mini,maxi)]
print(slices)
print(matrix[slices])
print(matrix[mini[0]:maxi[0], mini[1]:maxi[1]])
I've 2 values and I would like to find them in a array.
This values have the same index
Example:
0 0
1 2
2 3
4 5
I'm looking for (1,2) so the index is 2
M = [[0 0]; [1 2]; [2 3]; 4 5]
ex = [1, 2]
[~ r] = ismember(ex,M, 'rows')
I think this is what you're after.
If you're not looking to match the whole row but just columns 2 and 3 then:
[~, r] = ismember(ex, M(:,2:3), 'rows')
find(example(1:end-1)==val(1) & example(2:end) ==val(2))
or if you have the right tool box (econ?) use lagmatrix and bsxfun to compare entire rows.