How to trim a series of arrays in Matlab by eliminating elements - arrays

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);

Related

NumPy Slicing HackerRank

I have wrote a function named array_slice which gets four numbers n, n_dim, n_row, n_col from the user and performs array operations given below.
Instructions:
Create an array x of shape (n_dim, n_row, n_col), having first n natural numbers.
Create a Boolean array b of shape (2,).
Print the values for following expressions: x[b] and x[b,:,1:3]
For example if we have input 30, 2, 3, 5, for each corresponding parameters n, n_dim, n_row, n_col, Then the output prints will be as:
[[[ 0 1 2 3 4] [ 5 6 7 8 9] [10 11 12 13 14]]]
[[[ 1 2] [ 6 7] [11 12]]]
The written code is:
import numpy as np
# Enter your code here. Read input from STDIN. Print output to STDOUT
def array_slice(n,n_dim,n_row,n_col):
x=np.array(n, dtype=int, ndmin=n_dim).reshape(n_row,n_col)
b=np.array([True,False],dtype="bool",ndmin=n_dim).reshape(2,)
print(x[b])
print(x[b,:,1:3])
if __name__ == '__main__':
n = int(input())
n_dim = int(input())
n_row = int(input())
n_col = int(input())
array_slice(n,n_dim,n_row,n_col)
I went through official documentation NumPy, but still couldn't understand the error. I tried all possible ways with arange and array but I'm unable to get solution. Please help me out
This passed all test cases:
x = np.arange(n, dtype=int).reshape(n_dim, n_row, n_col)
b = np.array([True, False], dtype="bool", ndmin=n_dim).reshape(2,)
print(x[b])
print(x[b, :, 1:3])
I have tried the following code for x array using np.arrange:
x = np.arange(n, dtype=int).reshape(n_dim, n_row, n_col)
it will work:
[[[ 0 1 2 3 4]
[ 5 6 7 8 9]
[10 11 12 13 14]]]
[[[ 1 2]
[ 6 7]
[11 12]]]

How to remove duplicates from a numpy array with multiple dimensions

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

Matlab: creating a bigger array using a smaller array

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

Triangular part of a table

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

Extracting Columns iteratively from 2 different m-by-n matrices and concatenating in a set of n different m-by-2 matrices

MATLAB:
In MATLAB,
I have 2 m-by-n matrices, A and B. I want to make a set of n
m-by-2 matrices such as in ith matrix (of set of n), first column will be ith
column from A and second column will be ith column from B.
How to extract and concatenate ith columns from both matrices?
How I can store these n matrices? Using loops? (Memory?)
Example:
Input:
A = [ 1, 2, 3; 4, 5 ,6; 7, 8, 9] (3x3 matrix)
B = [ 11, 22, 33; 44, 55 ,66; 77, 88, 99] (3x3 matrix)
Output:
For i=1:3
C1 = [1, 11; 4, 44; 7, 77]
C2 = [2, 22; 5, 55; 8, 88]
C3 = [3, 33; 6, 66; 9, 99]
The first thing I'm going to do is change your variable names. Mainly this is just to make referring to the variables easier, especially as m and n change. Instead of writing
C1(:,:)
C2(:,:)
...
Cn(:,:)
I'm going to write
C(:,:,1)
C(:,:,2)
...
C(:,:,n)
All I've done is moved the index from the variable name to the index of the 3rd dimension.
Now, to create the C array:
A = [ 1, 2, 3; 4, 5 ,6; 7, 8, 9]
B = [ 11, 22, 33; 44, 55 ,66; 77, 88, 99]
[m,n]=size(A)
C = reshape([A',B']', m, 2, n)
The output of this is:
A =
1 2 3
4 5 6
7 8 9
B =
11 22 33
44 55 66
77 88 99
m = 3
n = 3
C =
ans(:,:,1) =
1 11
4 44
7 77
ans(:,:,2) =
2 22
5 55
8 88
ans(:,:,3) =
3 33
6 66
9 99
As you can see, C(:,:,1) is equal to C1 in your example, C(:,:,2) = C2 and so on. And this extends without change as the sizes of A and B change. You never have to come up with new variable names. And all you have to do to know how many m-by-2 matrices you've got is
numVars = size(C,3);
Note: This uses the same technique found in the answer here: matlab - how to merge/interlace 2 matrices?

Resources