I would like to access the lower triangular part of a (square) table with cell elements. I tried the tril function, but it doesn't work for input arguments of type 'cell'. Is there any workaround? Thanks.
Is this what you want?
c = {1, [2 3], 4; [5 6 7], [8 9], 10; 11, 12, [13 14]}; %// example 3x3 cell array
mask = tril(true(size(c,1), size(c,2))); %// creat mask
result = c(mask); %// index cell array with mask
This produces a column cell array with the selected cells in column-major order:
result{1} =
1
result{2} =
5 6 7
result{3} =
11
result{4} =
8 9
result{5} =
12
result{6} =
13 14
Related
Lets say I have the following array:
board = np.random.randint(1, 9, size=(2, 5))
How do I remove duplicates from each element in the array
e.g.
[[6 1 2 8 4]
[8 3 2 3 6]]
So here there are two 3s, and I want one of those to be deleted, how can I perform such an action?
Given your example, it seems that you don't want repetition relatively to rows. You may be interested in numpy.random.choice and try something like this:
import numpy as np
nb_lines = 2
nb_columns = 5
min_value = 1
max_value = 9
range_value = max_value-min_value
# The number of columns should be <= than the integer range to have a solution
assert(range_value+1 >= nb_columns)
board = min_value + np.array([
np.random.choice(np.arange(range_value+1), nb_columns, replace=False)
for l in range(nb_lines)
])
print(board)
Output:
% python3 script.py
[[7 4 6 3 1]
[2 8 6 4 3]]
I have a MATLAB array and want to make a repetition based on the number of array elements. Below is the example that I want.
a = [2, 4, 6, 8]
If I want 7 elements, the result is
aa = [2, 4, 6, 8, 2, 4, 6]
Or if I want 5 elements,
aa = [2, 4, 6, 8, 2]
Is there any MATLAB function which makes these kind of result?
You can use "modular indexing":
a = [2, 4, 6, 8]; % data vector
n = 7; % desired number of elements
aa = a(mod(0:n-1, numel(a))+1);
One simple option will be to use a temporary variable for that:
a = [2 4 6 8];
k = 7;
tmp = repmat(a,1,ceil(k/numel(a)));
aa = tmp(1:k)
First, you repeat the vector using the smallest integer that makes the result larger than k, and then you remove the excess elements.
If you do that many times you can write a small helper function to do that:
function out = semi_repmat(arr,k)
tmp = repmat(arr,1,ceil(k/numel(arr)));
out = tmp(1:k);
end
I wonder if there is a way of looping through a number of arrays of different sizes and trimming data from the beginning of each array in order to achieve the same amount of elements in each array?
For instance, if I have:
A = [4 3 9 8 13]
B = [15 2 6 11 1 12 8 9 10 13 4]
C = [2 3 11 12 10 9 15 4 14]
and I want B an C to lose some elements at the beginning, such that they end up being 5 elements in length, just like A, to achieve:
A = [4 3 9 8 13]
B = [8 9 10 13 4]
C = [10 9 15 4 14]
How would I do that?
EDIT/UPDATE:
I have accepted the answer proposed by #excaza, who wrote a nice function called "naivetrim". I saved that function as a .m script and then used it: First I define my three arrays and, as #excaza suggests, called the function:
[A, B, C] = naivetrim(A, B, C);
Another solution variation that worked for me - based on #Sardar_Usama's answer below (looping it). I liked this as well, because it was a bit more straightforward (with my level, I can follow what is happening in the code)
A = [4 3 9 8 13]
B = [15 2 6 11 1 12 8 9 10 13 4]
C = [2 3 11 12 10 9 15 4 14]
arrays = {A,B,C}
temp = min([numel(A),numel(B), numel(C)]); %finding the minimum number of elements
% Storing only required elements
for i = 1:size(arrays,2)
currentarray = arrays{i}
arrays(i) = {currentarray(end-temp+1:end)}
end
A naive looped solution:
function testcode()
% Sample data arrays
A = [4, 3, 9, 8, 13];
B = [15, 2, 6, 11, 1, 12, 8, 9, 10, 13, 4];
C = [2, 3, 11, 12, 10, 9, 15, 4, 14];
[A, B, C] = naivetrim(A, B, C);
end
function varargout = naivetrim(varargin)
% Assumes all inputs are vectors
% Find minumum length
lengths = zeros(1, length(varargin), 'uint32'); % Preallocate
for ii = 1:length(varargin)
lengths(ii) = length(varargin{ii});
end
% Loop through input arrays and trim any that are longer than the shortest
% input vector
minlength = min(lengths);
varargout = cell(size(varargin)); % Preallocate
for ii = 1:length(varargout)
if length(varargin{ii}) >= minlength
varargout{ii} = varargin{ii}(end-minlength+1:end);
end
end
end
Which returns:
A =
4 3 9 8 13
B =
8 9 10 13 4
C =
10 9 15 4 14
If you have a large number of arrays you may be better off with alternative intermediate storage data types, like cells or structures, which would be "simpler" to assign and iterate through.
Timing code for a few different similar approaches can be found in this Gist.
Performance Profile, MATLAB (R2016b)
Number of Elements in A: 999999
Number of Elements in B: 424242
Number of Elements in C: 101325
Trimming, deletion: 0.012537 s
Trimming, copying: 0.000430 s
Trimming, cellfun copying: 0.000493 s
If there are not many matrices then it can be done as:
temp = min([numel(A),numel(B), numel(C)]); %finding the minimum number of elements
% Storing only required elements
A = A(end-temp+1:end);
B = B(end-temp+1:end);
C = C(end-temp+1:end);
I have two giant array which looks like:
A = [11, 11, 12, 3, 3, 4, 4, 4 ];
B = [ 12, 4; 3, 11; 11, 1; 4, 13 ];
I want to create an array which takes values from B and column 1 from A to look like:
C = [ 11, 1; 11, 1; 12, 4; 3, 11; 3, 11; 4, 13; 4, 13; 4, 13 ];
I don't want to use for or any other kind of loop to optimize the process.
Sorry for being terse.
I will search each element from column 1 of A in column 1 of B and pick the corresponding column 2 elements from B and create a new array with column 1 elements of A and discovered column 2 elements from B.
What you are doing in this problem is using A and searching the first column of B to see if there's a match. Once there's a match, extract out the row that corresponds to this matched location in B. Repeat this for the rest of the values in A.
Assuming that all values of A can be found in B and that the first column of B is distinct and that there are no duplicates, you can a unique call and sortrows call. The unique call is on A so that you can assign each value in A to be a unique label in sorted order. You would then use these labels to index into the sorted version of B to get your desired result:
[~,~,id] = unique(A);
Bs = sortrows(B);
C = Bs(id,:);
We get for C:
C =
11 1
11 1
12 4
3 11
3 11
4 13
4 13
4 13
Thanks to #rayryeng for clarifying the question to me.
Assuming each element from A is present in column 1 of B:
[~, ind] = max(bsxfun(#eq, A(:).', B(:,1)), [], 1);
C = B(ind,:);
If that assumption doesn't necessarily hold:
[val, ind] = max(bsxfun(#eq, A(:).', B(:,1)), [], 1);
C = B(ind(val),:);
So for example A = [11, 20, 12, 3, 3, 4, 4, 4 ]; would produce
C =
11 1
12 4
3 11
3 11
4 13
4 13
4 13
I have a vector [x, y, ...] in Octave and I would like to take the pth powers of the elements to get the new vector [x^p, y^p, ...]. Anybody has an idea how to do this?
v = [1, 2, 3, 4, 5];
p = 2;
w = v.^p;
Output (ideone):
1 2 3 4 5
1 4 9 16 25
If you want to apply an operation element wise to a vector/matrix, prepend the operator with a dot:
b=[1,2,3,4,5,6];
b2=b.^2;