half the dimension of a numpy array [duplicate] - python

This question already has answers here:
how to perform max/mean pooling on a 2d array using numpy
(8 answers)
Closed 7 months ago.
Lets say I have a numpy array of 4x4 dimension and want to change it to 2x2 by taking its halve. So, theoretically do something like this:
is this possible without using any loop and for it to work on not only a 4x4 but lets say a 500x500?
#input:
x_4= np.array([[1, 2, 4, 5], [3, 4, 6, 8], [5, 3, 1, -1], [2, 3, 5, 0]])
# thinking it would work with something like this:
new = x_4[:2, :2]/4 + x_4[:2, -2:]/4 + x_4[-2:, :2]/4 + x_4[-2:, -2:]/4
new
# output: array([[11, 9],[16, 15]])
#Expected output: array([[2.5, 5.75], [3.25, 1.25]])

Numpy Version:
you can do a reshape and perform mean over two axis to get the desired result
import numpy as np
blocksize = 500
Mat = np.random.rand(blocksize,blocksize)
## reshape into (blocksize/2 x blocksize/2 ) 2x2 matrices
blocks = Mat.reshape(blocksize//2, 2, blocksize//2, 2)
block_mean = np.mean(blocks, axis=(1,-1))

As was pointed out in the comments, you can use pooling, which is e.g. available in the scikit-image package:
import skimage.measure
shape = (2, 2)
skimage.measure.block_reduce(x_4, shape, np.mean)
Where shape gives you the dimensions of your pools.

This Operation called average Pooling it used in CNN and image processing to reduce the dimension of the image
you can use TensorFlow or PyTorch first you need to reshape the image to (batch_size,Channels,Rows,Columns) for PyTorch to work
import numpy as np
import torch
from torch import nn
m= nn.AvgPool2d(2, stride=2)
x_4= np.array([[1, 2, 4, 5], [3, 4, 6, 8], [5, 3, 1, -1], [2, 3, 5, 0]])
x_4=x_4[None,None,:,:]
x_4=torch.as_tensor(x_4,dtype=torch.float64)
x_4.shape
m(x_4).numpy()
Output
array([[[[2.5 , 5.75],
[3.25, 1.25]]]])

Related

Fill numpy array with other numpy array

I have following numpy arrays:
whole = np.array(
[1, 0, 3, 0, 6]
)
sparse = np.array(
[9, 8]
)
Now I want to replace every zero in the whole array in chronological order with the items in the sparse array. In the example my desired array would look like:
merged = np.array(
[1, 9, 3, 8, 6]
)
I could write a small algorithm by myself to fix this but if someone knows a time efficient way to solve this I would be very grateful for you help!
Do you assume that sparse has the same length as there is zeros in whole ?
If so, you can do:
import numpy as np
from copy import copy
whole = np.array([1, 0, 3, 0, 6])
sparse = np.array([9, 8])
merge = copy(whole)
merge[whole == 0] = sparse
if the lengths mismatch, you have to restrict to the correct length using len(...) and slicing.

How can I multiply numpy matrix elementwise without for loops?

I would like to apply the same matrix (3x3) to a large list of points that are contained in a vector. The vector is of the form (40000 x 3). The below code does the job but it is too slow. Are there any numpy tricks I can use to eliminate the for loop and append function?
def apply_matrix_to_shape(Matrix,Points):
"""input a desired transformation and an array of points that are in
the format np.array([[x1,y1,z1],[x2,y2,z2],...,]]). will output
a new array of translated points with the same format"""
New_shape = np.array([])
M = Matrix
for p in Points:
New_shape = np.append(New_shape,[p[0]*M[0][0]+p[1]*M[0][1]+p[2]*M[0][2],
p[0]*M[1][0]+p[1]*M[1][1]+p[2]*M[1][2],
p[0]*M[2][0]+p[1]*M[2][1]+p[2]*M[2][2]])
Rows = int(len(New_shape) / 3)
return np.reshape(New_shape,(Rows,3))
You basically want the matrix multiplication of both arrays (not an element-wise one). You just need to tranpose so the shapes are aligned, and transpose back the result:
m.dot(p.T).T
Or equivalently:
(m#p.T).T
m = np.random.random((3,3))
p = np.random.random((15,3))
np.allclose((m#p.T).T, apply_matrix_to_shape(m, p))
# True
Indeed, I think what you want is one of the main reason why NumPy came to live. You can use the dot product function and the transpose function (simply .T or .transpose())
import numpy as np
points = np.array([[1, 2, 3],
[4, 5, 6]])
T_matrix = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
result = points.dot(T_matrix.T)
print(result)
>>> [[ 14 32 50]
[ 32 77 122]]

Add mutiple 2D array into 3D array in a for loop

I encountered a problem in python programming.
I was manipulating the feature extraction in deep learning. I would like to add several 2D arrays into a 3D array in a for loop. I could achieve the purpose by using this easy way shown below. This method is not realistic in a large sample.
But in my situation, the data returned in the function of one sample is a 2D array (i.e. shape is (41,4)), the data itself is in the loop (i.e. 30 samples), the results I would like to obtain is a 3D array (i.e. shape is (30,41,4)).
I didn't find any related information, I really stuck here, hope someone could help me.
import numpy as np
a = np.array([[1,2,3],[4,5,6]])
b = np.array([[2,2,3],[4,5,6]])
c = np.array([[3,2,3],[4,5,6]])
print(a)
print(a.shape)
com = np.array([a,b,c])
print(com)
print(com.shape)
You can use np.stack
>>> arr = np.stack((a,b,c))
>>> arr
array([[[1, 2, 3],
[4, 5, 6]],
[[2, 2, 3],
[4, 5, 6]],
[[3, 2, 3],
[4, 5, 6]]])
>>> arr.shape
(3, 2, 3)

Convert dense tensor to ragged tensor

I have a Sparse Tensor which I converted into Dense Tensor. After converting from sparse to dense using tf.sparse.to_dense, I got an output which looks like this:
I want to remove default values i.e zero and convert it to ragged tensor like this:
Data in the above two images is different
I went through Tensorflow documentation and I am unable to find any method to do this. I tried using boolean_mask, the major problem is to compute boolean_mask for each row individually.
So, I am wondering if there is an efficient way to achieve this.
Thank you.
tf.RaggedTensor.from_tensor removes specific value from tensor of any dimensionality.
x = [[1, 3, -1, -1], [2, -1, -1, -1], [4, 5, 8, 9]]
print(tf.RaggedTensor.from_tensor(x, padding=-1))
Output: <tf.RaggedTensor [[1, 3], [2], [4, 5, 8, 9]]>

Need help converting Matlab's bsxfun to numpy

I'm trying to convert a piece of MATLAB code, and this is a line I'm struggling with:
f = 0
wlab = reshape(bsxfun(#times,cat(3,1-f,f/2,f/2),lab),[],3)
I've come up with
wlab = lab*(np.concatenate((3,1-f,f/2,f/2)))
How do I reshape it now?
Not going to do it for your code, but more as a general knowledge:
bsxfun is a function that fills a gap in MATLAB that python doesn't need to fill: broadcasting.
Broadcasting is a thing where if a matrix that is being multiplied/added/whatever similar is not the same size as the other one being used, the matrix will be repeated.
So in python, if you have a 3D matrix A and you want to multiply every 2D slice of it with a matrix B that is 2D, you dont need anything else, python will broadcast B for you, it will repeat the matrix again and again. A*B will suffice. However, in MATLAB that will raise an error Matrix dimension mismatch. To overcome that, you'd use bsxfun as bsxfun(#times,A,B) and this will broadcast (repeat) B over the 3rd dimension of A.
This means that converting bsxfun to python generally requires nothing.
MATLAB
reshape(x,[],3)
is the equivalent of numpy
np.reshape(x,(-1,3))
the [] and -1 are place holders for 'fill in the correct shape here'.
===============
I just tried the MATLAB expression is Octave - it's on a different machine, so I'll just summarize the action.
For lab=1:6 (6 elements) the bsxfun produces a (1,6,3) matrix; the reshape turns it into (6,3), i.e. just removes the first dimension. The cat produces a (1,1,3) matrix.
np.reshape(np.array([1-f,f/2,f/2])[None,None,:]*lab[None,:,None],(-1,3))
For lab with shape (n,m), the bsxfun produces a (n,m,3) matrix; the reshape would make it (n*m,3)
So for a 2d lab, the numpy needs to be
np.array([1-f,f/2,f/2])[None,None,:]*lab[:,:,None]
(In MATLAB the lab will always be 2d (or larger), so this 2nd case it closer to its action even if n is 1).
=======================
np.array([1-f,f/2,f/2])*lab[...,None]
would handle any shaped lab
If I make the Octave lab (4,2,3), the `bsxfun is also (4,2,3)
The matching numpy expression would be
In [94]: (np.array([1-f,f/2,f/2])*lab).shape
Out[94]: (4, 2, 3)
numpy adds dimensions to the start of the (3,) array to match the dimensions of lab, effectively
(np.array([1-f,f/2,f/2])[None,None,:]*lab) # for 3d lab
If f=0, then the array is [1,0,0], so this has the effect of zeroing values on the last dimension of lab. In effect, changing the 'color'.
It is equivalent to
import numpy as np
wlab = np.kron([1-f,f/2,f/2],lab.reshape(-1,1))
In Python, if you use numpy you do not need to do any broadcasting, as this is done automatically for you.
For instance, looking at the following code should make it clearer:
>>> import numpy as np
>>> a = np.array([[1, 2, 3], [3, 4, 5], [6, 7, 8], [9, 10, 100]])
>>> b = np.array([1, 2, 3])
>>>
>>> a
array([[ 1, 2, 3],
[ 3, 4, 5],
[ 6, 7, 8],
[ 9, 10, 100]])
>>> b
array([1, 2, 3])
>>>
>>> a - b
array([[ 0, 0, 0],
[ 2, 2, 2],
[ 5, 5, 5],
[ 8, 8, 97]])
>>>

Categories

Resources