Python NumPy shape - python

Can someone please explain this code to me
case = np.array([[1,2], [2,4], [3,5]])
I understand the above gives 2 columns and 3 rows.
But the code below I don't understand. Please help me to understand it.
np.arange(0, case.shape[0]+4)

np.arange() returns evenly spaced values within a given interval.
In this case, since case.shape[0] is the first axis of the array, which has 3 arrays in it, the range goes from 0 to 3+4=7 (end not included).

case = np.array([[1,2], [2,4], [3,5]])
case
array([[1, 2],
[2, 4],
[3, 5]])
Numpy.arange will provide a series of numbers starts from 0 to case.shape[0] +4 . Here case.shape is (3,2) (Three Rows and Two Columns) . So Case[0] will be 3 and case[1] will be 2 . So np.arrange will be a series of numbers from 0 to 3+4 = 7 where 0 is included and 7 is excluded and output will be 0,1,2,3,4,5,6

Related

How to construct a rank array with numpy? (What is a rank array?)

I hope all of you are having a great day. In my python class, we are learning how to use Numpy, so we got an assignment about that. My question is this: What is a rank array and how can I construct that with using python? My instructor tried to explain that with these lines but I did not understand anything actually :(
These are the instructions:
rank_calculator(A) - 5 pts
Given a numpy ndarray A, return its rank array.
Input: [[ 9 4 15 0 18]
[16 19 8 10 1]]
Return value: [[4 2 6 0 8]
[7 9 3 5 1]]
The return value should be an ndarray of the same size and shape as the original array A.
So, can someone explain that? I am not so good at Python, unfortunately :(
You can use numpy.argsort multiple times to handle a matrix, as suggested in this answer on SO.
import numpy as np
inp = np.array([[9,4,15,0,18],
[16,19,8,10,1]])
inp.ravel().argsort().argsort().reshape(inp.shape)
array([[4, 2, 6, 0, 8],
[7, 9, 3, 5, 1]])
What is a rank matrix?
In summary, if I were to take all the integers in the matrix, and sort them smallest to largest, then assign each one a rank from 0 to 9, that would result in the rank matrix. Notice that the smallest is 0 which gets a rank of 0, while largest is 19, which gets the last rank of 9.
How the double argsort works
#printing them so they align nicely
print('Array ->', end='')
for i in inp.ravel().astype('str'):
print(i.center(4), end='')
print('\n')
print('Sort1 ->', end='')
for i in inp.ravel().argsort().astype('str'):
print(i.center(4), end='')
print('\n')
print('Sort2 ->', end='')
for i in inp.ravel().argsort().argsort().astype('str'):
print(i.center(4), end='')
Array -> 9 4 15 0 18 16 19 8 10 1
Sort1 -> 3 9 1 7 0 8 2 5 4 6
Sort2 -> 4 2 6 0 8 7 9 3 5 1
Let's first summarize what argsort does. It takes the position of each element and puts them where they belong after sorting. Knowing this, we can write a backward logic which is sort of triangular in nature. Lets start from sort2, then sort1 and then array.
0th (in sort2) is 4th (in sort1), 4th (in sort1) is 0th (in array). So 0th (in array) is 0th (in sort2)
9th (in sort2) is 1st (in sort1), 1st (in sort1) is 9th (in array). So, 9th (in array) is 9th (in sort2)
6th (in sort2) is 9th (in sort1), 9th (in sort1) is 6th (in array). So, 6th (in array) is 6th (in sort2)
Its a bit confusing to wrap your head around it, but once you can understand how argsort() works, you shouldn't have a problem.
Q) What is a rank array?
Ans: It's basically the elements in their sorted order.
Basically what your teacher is asking you is to return each elements positions if they were sorted in ascending order.
CODE:
import numpy as np
A = np.array([[9, 4, 15, 0, 18],
[16, 19, 8, 10, 1]])
flatA = A.flatten()
sorted_flatA = sorted(flatA) # will become -> [0, 1, 4, 8, 9, 10, 15, 16, 18, 19]
# Using a 'MAP' to map the values of sorted_faltA to the index of sorted_faltA.
MAP = {}
for i in range(len(sorted_flatA)):
MAP[sorted_flatA[i]] = i
# Then simply going through the 2D array snd replacing the with their ranks.
res = np.zeros(A.shape)
for i in range(A.shape[0]):
for j in range(A.shape[1]):
res[i][j] = MAP[A[i][j]]
print(res)

How do I reverse the first four elements of the 1st axis and reversing the 2nd axis of a numpy array in a single operation?

I have a numpy array M of shape (n, 1000, 6). This can be thought of as n matrices with 1000 rows and 6 columns. For each matrix I would like to reverse the order of the rows (i.e. the top row is now at the bottom and vice versa) and then reverse the order of just the first 4 columns (so column 0 is now column 3, column 1 is column 2, column 2 is column 1 and column 3 is column 0 but column 4 is still column 4 and column 5 is still column 5). I would like to do this in a single operation, without doing indexing on the left side of the expression, so this would not be acceptable:
M[:,0:4,:] = M[:,0:4,:][:,::-1,:]
M[:,:,:] = M[:,:,::-1]
The operation needs to be achieveable using Keras backend which disallowes this. It must be of the form
M = M[indexing here that solves the task]
If I wanted to reverse the order of all the columns instead of just the first 4 this could easily be achieved with M = M[:,::-1,::-1] so I've being trying to modify this to achieve my goal but unfortunately can't work out how. Is this even possible?
M[:, ::-1, [3, 2, 1, 0, 4, 5]]

Do numpy 1D arrays follow row/column rules?

I have just started using numpy and I am getting confused about how to use arrays. I have seen several Stack Overflow answers on numpy arrays but they all deal with how to get the desired result (I know how to do this, I just don't know why I need to do it this way). The consensus that I've seen is that arrays are better than matrices because they are a more basic class and less restrictive. I understand you can transpose an array which to me means there is a distinction between a row and a column, but the multiplication rules all produce the wrong outputs (compared to what I am expecting).
Here is the test code I have written along with the outputs:
a = numpy.array([1,2,3,4])
print(a)
>>> [1 2 3 4]
print(a.T) # Transpose
>>> [1 2 3 4] # No apparent affect
b = numpy.array( [ [1], [2], [3], [4] ] )
print(b)
>>> [[1]
[2]
[3]
[4]] # Column (Expected)
print(b.T)
>>> [[1 2 3 4]] # Row (Expected, transpose seems to work here)
print((b.T).T)
>>> [[1]
[2]
[3]
[4]] # Column (All of these are as expected,
# unlike for declaring the array as a row vector)
# The following are element wise multiplications of a
print(a*a)
>>> [ 1 4 9 16]
print(a * a.T) # Row*Column
>>> [ 1 4 9 16] # Inner product scalar result expected
print(a.T * a) # Column*Row
>>> [ 1 4 9 16] # Outer product matrix result expected
print(b*b)
>>> [[1]
[4]
[9]
[16]] # Expected result, element wise multiplication in a column
print(b * b.T) # Column * Row (Outer product)
>>> [[ 1 2 3 4]
[ 2 4 6 8]
[ 3 6 9 12]
[ 4 8 12 16]] # Expected matrix result
print(b.T * (b.T)) # Column * Column (Doesn't make much sense so I expected elementwise multiplication
>>> [[ 1 4 9 16]]
print(b.T * (b.T).T) # Row * Column, inner product expected
>>> [[ 1 2 3 4]
[ 2 4 6 8]
[ 3 6 9 12]
[ 4 8 12 16]] # Outer product result
I know that I can use numpy.inner() and numpy.outer() to achieve the affect (that is not a problem), I just want to know if I need to keep track of whether my vectors are rows or columns.
I also know that I can create a 1D matrix to represent my vectors and the multiplication works as expected. I'm trying to work out the best way to store my data so that when I look at my code it is clear what is going to happen - right now the maths just looks confusing and wrong.
I only need to use 1D and 2D tensors for my application.
I'll try annotating your code
a = numpy.array([1,2,3,4])
print(a)
>>> [1 2 3 4]
print(a.T) # Transpose
>>> [1 2 3 4] # No apparent affect
a.shape will show (4,). a.T.shape is the same. It kept the same number of dimensions, and performed the only meaningful transpose - no change. Making it (4,1) would have added a dimension, and destroyed the A.T.T roundtrip.
b = numpy.array( [ [1], [2], [3], [4] ] )
print(b)
>>> [[1]
[2]
[3]
[4]] # Column (Expected)
print(b.T)
>>> [[1 2 3 4]] # Row (Expected, transpose seems to work here)
b.shape is (4,1), b.T.shape is (1,4). Note the extra set of []. If you'd created a as a = numpy.array([[1,2,3,4]]) its shape too would have been (1,4).
The easy way to make b would be b=np.array([[1,2,3,4]]).T (or b=np.array([1,2,3,4])[:,None] or b=np.array([1,2,3,4]).reshape(-1,1))
Compare this to MATLAB
octave:3> a=[1,2,3,4]
a =
1 2 3 4
octave:4> size(a)
ans =
1 4
octave:5> size(a.')
ans =
4 1
Even without the extra [] it has initialed the matrix as 2d.
numpy has a matrix class that imitates MATLAB - back in the time when MATLAB allowed only 2d.
In [75]: m=np.matrix('1 2 3 4')
In [76]: m
Out[76]: matrix([[1, 2, 3, 4]])
In [77]: m.shape
Out[77]: (1, 4)
In [78]: m=np.matrix('1 2; 3 4')
In [79]: m
Out[79]:
matrix([[1, 2],
[3, 4]])
I don't recommend using np.matrix unless it really adds something useful to your code.
Note the MATLAB talks of vectors, but they are really just their matrix with only one non-unitary dimension.
# The following are element wise multiplications of a
print(a*a)
>>> [ 1 4 9 16]
print(a * a.T) # Row*Column
>>> [ 1 4 9 16] # Inner product scalar result expected
This behavior follows from a.T == A. As you noted, * produces element by element multiplication. This is equivalent to the MATLAB .*. np.dot(a,a) gives the dot or matrix product of 2 arrays.
print(a.T * a) # Column*Row
>>> [ 1 4 9 16] # Outer product matrix result expected
No, it is still doing elementwise multiplication.
I'd use broadcasting, a[:,None]*a[None,:] to get the outer product. Octave added this in imitation of numpy; I don't know if MATLAB has it yet.
In the following * is always element by element multiplication. It's broadcasting that produces matrix/outer product results.
print(b*b)
>>> [[1]
[4]
[9]
[16]] # Expected result, element wise multiplication in a column
A (4,1) * (4,1)=>(4,1). Same shapes all around.
print(b * b.T) # Column * Row (Outer product)
>>> [[ 1 2 3 4]
[ 2 4 6 8]
[ 3 6 9 12]
[ 4 8 12 16]] # Expected matrix result
Here (4,1)*(1,4)=>(4,4) product. The 2 size 1 dimensions have been replicated so it becomes, effectively a (4,4)*(4,4). How would you do replicate this in MATLAB - with .*?
print(b.T * (b.T)) # Column * Column (Doesn't make much sense so I expected elementwise multiplication
>>> [[ 1 4 9 16]]
* is elementwise regardless of expectations. Think b' .* b' in MATLAB.
print(b.T * (b.T).T) # Row * Column, inner product expected
>>> [[ 1 2 3 4]
[ 2 4 6 8]
[ 3 6 9 12]
[ 4 8 12 16]] # Outer product result
Again * is elementwise; inner requires a summation in addition to multiplication. Here broadcasting again applies (1,4)*(4,1)=>(4,4).
np.dot(b,b) or np.trace(b.T*b) or np.sum(b*b) give 30.
When I worked in MATLAB I frequently checked the size, and created test matrices that would catch dimension mismatches (e.g. a 2x3 instead of a 2x2 matrix). I continue to do that in numpy.
The key things are:
numpy arrays may be 1d (or even 0d)
A (4,) array is not exactly the same as a (4,1) or (1,4)`.
* is elementwise - always.
broadcasting usually accounts for outer like behavior
"Transposing" is, from a numpy perspective, really only a meaningful concept for two-dimensional structures:
>>> import numpy
>>> arr = numpy.array([1,2,3,4])
>>> arr.shape
(4,)
>>> arr.transpose().shape
(4,)
So, if you want to transpose something, you'll have to make it two-dimensional:
>>> arr_2d = arr.reshape((4,1)) ## four rows, one column -> two-dimensional
>>> arr_2d.shape
(4, 1)
>>> arr_2d.transpose().shape
(1, 4)
Also, numpy.array(iterable, **kwargs) has a key word argument ndmin, which will, set to ndmin=2 prepend your desired shape with as many 1 as necessary:
>>> arr_ndmin = numpy.array([1,2,3,4],ndmin=2)
>>> arr_ndmin.shape
(1, 4)
Yes, they do.
Your question is already answered. Though I assume you are a Matlab user? If so, you may find this guide useful: Moving from MATLAB matrices to NumPy arrays

Matrix addition: combinations of elements that sum up to a specific value

using Python,
I have two matrices A and B of size 100,000x25 and a vector C of size 25.
I know for loops are slow so I want an efficient way of adding every combination of numbers from A with B and C and collecting all indices of those elements that sum greater than 10.
Small Example for demonstrating
_____
A =
[1, 2 ]
[5, 8 ]
B =
[3, 6]
[4, 2]
C= [3,4,7,1]
In the above example, A[0,1]+B[0,0]+C[0] = 5+3+3 =11 which is what I am trying to find I.e all combinations that sum upto a specific value.
I tried for loops but takes way long. And my estimate is almost 2 days for the matrices that I have. Any suggestions?

Perform function on multiple columns in python

I have a data array of 30 trials(columns) each of 256 data points (rows) and would like to run a wavelet transform (which requires a 1D array) on each column with the eventual aim of obtaining the mean coefficients of the 30 trials.
Can someone point me in the right direction please?
If you have a multidimensional numpy array then you can use a for loop:
import numpy as np
A = np.array([[1,2,3], [4,5,6]])
# A is the matrix: 1 2 3
# 4 5 6
for col in A.transpose():
print("Column:", col)
# Perform your wavelet transform here, you can save the
# results to another multidimensional array.
This gives you access to each column as a 1D array.
Output:
Column: [1 4]
Column: [2 5]
Column: [3 6]
If you want to access the rows rather than the columns then loop through A rather than A.transpose().

Categories

Resources