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]]
Related
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]]]
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 an array. I sorted it, so I have sorted array and indeces of sorted elements in the initial array.
Fo example, from [4 5 4 4 4 4 5 4] I got [4 4 4 4 4 4 5 5] and [1 3 4 5 6 8 2 7].
How to place recieved indeces in a cell array, so that in one cell will be indeces of equal elements? For my example, it will be: {1 3 4 5 6 8}, {2 7}.
I'm searching for non-loop way to solve it.
Use accumarray:
x = [4 5 4 4 4 4 5 4]; %// data
[~, ~, jj] = unique(x);
result = accumarray(jj(:), 1:numel(x), [], #(v) {v(:).'});
Or, if you need each set of indices sorted:
result = accumarray(jj(:), 1:numel(x), [], #(v) {sort(v(:)).'});
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
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.