NumPy Slicing HackerRank - arrays

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

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

Converting pandas data frame into numpy ndarray [duplicate]

This question already has answers here:
Convert pandas dataframe to NumPy array
(15 answers)
Closed 4 years ago.
I am using a pandas data frame to clean and process data. However, I need to then convert it into a numpy ndarray in order to use exploit matrix multiplication. I turn the data frame into a list of lists with the following:
x = df.tolist()
This returns the following structure:
[[1, 2], [3, 4], [5, 6], [7, 8] ...]
I then convert it into a numpy array like this:
x = np.array(x)
However, the following print:
print(type(x))
print(type(x[0]))
gives this result:
'numpy.ndarray'
'numpy.float64'
However, I need them both to be numpy arrays. If it's not from a pandas data frame and I just convert a hard-coded list of lists then they are both ndarrays. How do I get the list, and the lists in that list to be ndarrays when that list has been made from a data frame? Many thanks for reading, this has had me stumped for hours.
I think you need values:
df = pd.DataFrame({'C':[7,8,9,4,2,3],
'D':[1,3,5,7,1,0]})
print (df)
C D
0 7 1
1 8 3
2 9 5
3 4 7
4 2 1
5 3 0
x = df.values
print (x)
[[7 1]
[8 3]
[9 5]
[4 7]
[2 1]
[3 0]]
And then select by indexing:
print (x[:,0])
[7 8 9 4 2 3]
print (x[:,1])
[1 3 5 7 1 0]
print (type(x[:,0]))
<class 'numpy.ndarray'>
Also is possible transpose array:
x = df.values.T
print (x)
[[7 8 9 4 2 3]
[1 3 5 7 1 0]]
print (x[0])
[7 8 9 4 2 3]
print (x[1])
[1 3 5 7 1 0]
How about as_matrix:
x = df.as_matrix()
You may want to try df.get_values(), and eventually np.reshape it.

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

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

Transpose of a matrix in numpy

I have this numpy array:
a = np.array([[[1,2,3],[-1,-2,-3]],[[4,5,6],[-4,-5,-6]]])
b is a transpose of a. I want b be like this:
b = np.array([[[1,-1],[2,-2],[3,-3]],[[4,-4],[5,-5],[6,-6]]])
Is it possible to do it in one line?
EDIT:
And if I have this instead:
a = np.empty(3,dtype = object)
a[0] = np.array([[1,2,3],[-1,-2,-3]])
a[1] = np.array([[4,5,6],[-4,-5,-6]])
How can I get b?
You can do it using np.transpose(a,(0,2,1)):
In [26]: a = np.array([[[1,2,3],[-1,-2,-3]],[[4,5,6],[-4,-5,-6]]])
In [27]: b = np.transpose(a,(0,2,1))
In [28]: print a
[[[ 1 2 3]
[-1 -2 -3]]
[[ 4 5 6]
[-4 -5 -6]]]
In [29]: print b
[[[ 1 -1]
[ 2 -2]
[ 3 -3]]
[[ 4 -4]
[ 5 -5]
[ 6 -6]]]
For your edited question with an array of dtype=object -- there is no direct way to compute the transpose, because numpy doesn't know how to transpose a generic object. However, you can use list comprehension and transpose each object separately:
In [90]: a = np.empty(2,dtype = object)
In [91]: a[0] = np.array([[1,2,3],[-1,-2,-3]])
In [92]: a[1] = np.array([[4,5,6],[-4,-5,-6]])
In [93]: print a
[[[ 1 2 3]
[-1 -2 -3]] [[ 4 5 6]
[-4 -5 -6]]]
In [94]: b = np.array([np.transpose(o) for o in a],dtype=object)
In [95]: print b
[[[ 1 -1]
[ 2 -2]
[ 3 -3]]
[[ 4 -4]
[ 5 -5]
[ 6 -6]]]

Resources