Simple Numpy Reshape, same operation gives different shapes - python

I have the following section of code:
print X.shape
print Y.shape
X = X[np.where(X[:, 2] > 0.05)]
Y = Y[np.where(Y[:, 2] > 0.05)]
print X.shape
print Y.shape
print Y
The output of the code is:
(231, 3)
(231, 3)
(55, 3)
(1, 56)
[[-1.98769812 -1.93259862 -2.29080624 -0.83792838 -1.94892429 -1.58289539
-1.90247292 -1.4556473 -2.19070534 -1.73212961 -1.61395937 -1.14633543
-1.10683535 -1.02509949 -1.25594622 -1.4080105 -1.63474736 -1.95824227
-2.17106426 -1.91125435 -2.0718614 -1.89993348 -1.54472541 -0.87961375
-1.85216151 -2.121226 -1.88453394 -1.29166291 -1.78698561 -2.08983923
-2.02139995 -0.9349243 -0.90184218 -0.69882058 -1.05909316 -2.15477887
-1.43069109 -2.03090084 -0.5736147 -1.51153658 -2.22790561 -0.75759474
-1.76501869 -1.38221479 -1.17738909 -1.64007052 -1.88721801 -1.290115
-1.76288243 -2.08980588 -1.85872696 -1.79981182 -1.56103353 -1.41155315
-0.73043509 -1.27204526]]
I was expecting that the updated Y array would have the shape (56,3). How can the same operation on two numpy arrays of the same shape produce different shapes?

Related

Concatenate Numpy arrays of different shape

I would like to create a numpy array by concatenating two or more numpy arrays with shape (1, x, 1) where x is variable.
Here is the problem in detail.
x1 = #numpy array with shape (x,)
x2 = #numpy array with shape (y,)
#create batch
x1 = np.expand_dims(x1, 0) #shape (1, x)
x2 = np.expand_dims(x2, 0) #shape (1, y)
#add channel dimension
x1 = np.expand_dims(x1, -1) #shape (1, x, 1)
x2 = np.expand_dims(x2, -1) #shape (1, y, 1)
#merge the two arrays
x = np.concatenate((x1, x2), axis=0)
#expected shape (2, ??, 1)
Note the expected shape (2, ??, 1). I am wondering if what I am trying to do is doable.
Executing this code raises a ValueError:
ValueError: all the input array dimensions for the concatenation axis must match exactly, but along dimension 1, the array at index 0 has size 138241 and the array at index 1 has size 104321

Stack a list of numpy arrays

I have a list of numpy arrays that are of the following shapes:
(16, 250, 2)
(7, 250, 2)
(1, 250, 2)
I'm trying to stack them all together so they are a single numpy array of shape :
(24, 250, 2)
I tried using np.stack but I get the error:
ValueError: all input arrays must have the same shape
The trick is to use the right stacking method, in your case since you are stacking vertically you should use np.vstack
import numpy as np
a = np.random.random((16, 250, 2))
b = np.random.random((7, 250, 2))
c = np.random.random((1, 250, 2))
arr = np.vstack((a,b,c))
arr.shape
(24, 250, 2)
You can use np.concatenate: You will get this:-
a = np.random.rand(16,250,2)
b = np.random.rand(7,250,2)
c = np.random.rand(1,250,2)
print(np.shape(np.concatenate([a,b,c], axis=0))
Output:
(24,250,2)

Numpy dotproduct weird behaviour

I am using python3.5 and i have question: Why np.dot() is behaving like this?
>> a = np.array([[1,2,3,4]])
>> b = np.array([123])
>> np.dot(a,b)
Traceback (most recent call last):
File "<input>", line 1, in <module>
ValueError: shapes (1,4) and (1,) not aligned: 4 (dim 1) != 1 (dim 0)
>>np.dot(b,a)
array([123, 246, 369, 492])
From help(np.dot), we learn that, np.dot(x,y) is a sum product over the last axis of x and the second-to-last of y
In the case of np.dot(a, b), the last axis of a is 4 and the length of the only axis of b is 1. They don't match: fail.
In the case of np.dot(b, a), the last axis of b is 1 and the 2nd to last of a is 1. They match: success.
Workarounds
Depending on what your intention is for np.dot(a,b), you may want:
>>> np.dot(a, np.resize(b,a.shape[-1]))
array([1230])
From the documentation for numpy.dot(x, y):
For 2-D arrays it is equivalent to matrix multiplication, and for 1-D arrays to inner product of vectors... For N dimensions it is a sum product over the last axis of x and the second-to-last of y:
So, where you have:
a = np.array([[1,2,3,4]]) # shape is (1, 4), 2-D array (matrix)
b = np.array([123]) # shape is (1,), 1-D array (vector)
np.dot(b, a) works ((1,) * (1, 4), the relevant dimensions agree)
np.dot(a, b) doesn't ((1, 4) * (1,), the relevant dimensions don't agree, the operation is undefined. Note that the 'second-to-last' axis of (1,) corresponds to its one and only axis)
This is the same behaviour as if you have two 2-D arrays, i.e. matrices:
a = np.array([[1,2,3,4]]) # shape is (1, 4)
b = np.array([[123]]) # shape is (1, 1)
np.dot(b, a) works ((1, 1) * (1, 4), inner matrix dimensions agree)
np.dot(a, b) doesn't ((1, 4) * (1, 1), inner matrix dimensions don't agree)
If however you have two 1-D arrays, i.e. vectors, neither operation works:
a = np.array([1,2,3,4]) # shape is (4,)
b = np.array([123]) # shape is (1,)
np.dot(b, a) doesn't work ((1,) * (4,), but can only define the inner product for vectors of the same length)
np.dot(a, b) doesn't work ((4,) * (1), same)

Why is irfftn(rfftn(x)) not equal to x?

If the trailing dimension of an array x is odd, the transform y = irfftn(rfftn(x)) does not have the same shape as the input array. Is this by design? And if so, what is the motivation? Example code is below.
import numpy as np
shapes = [(10, 10), (11, 11), (10, 11), (11, 10)]
for shape in shapes:
x = np.random.uniform(0, 1, shape)
y = np.fft.irfftn(np.fft.rfftn(x))
if x.shape != y.shape:
print("expected shape %s but got %s" % (shape, y.shape))
# Output
# expected shape (11, 11) but got (11, 10)
# expected shape (10, 11) but got (10, 10)
You need to pass second parameter x.shape
in your case the code will looks like:
import numpy as np
shapes = [(10, 10), (11, 11), (10, 11), (11, 10)]
for shape in shapes:
x = np.random.uniform(0, 1, shape)
y = np.fft.irfftn(np.fft.rfftn(x),x.shape)
if x.shape != y.shape:
print("expected shape %s but got %s" % (shape, y.shape))
from the docs
This function computes the inverse of the N-dimensional discrete
Fourier Transform for real input over any number of axes in an
M-dimensional array by means of the Fast Fourier Transform (FFT). In
other words, irfftn(rfftn(a), a.shape) == a to within numerical
accuracy. (The a.shape is necessary like len(a) is for irfft, and for
the same reason.)
x.shape descriptions from the same docs:
s : sequence of ints, optional Shape (length of each transformed axis)
of the output (s[0] refers to axis 0, s[1] to axis 1, etc.). s is also
the number of input points used along this axis, except for the last
axis, where s[-1]//2+1 points of the input are used. Along any axis,
if the shape indicated by s is smaller than that of the input, the
input is cropped. If it is larger, the input is padded with zeros. If
s is not given, the shape of the input along the axes specified by
axes is used.
https://docs.scipy.org/doc/numpy/reference/generated/numpy.fft.irfftn.html

Pairing images as np arrays into a specific format

So I have 2 images, X and Y, as numpy arrays, each of shape (3, 30, 30): that is, 3 channels (RGB), each of height and width 30 pixels. I'd like to pair them up into a numpy array to get a specific output shape:
my_pair = pair_up_images(X, Y)
my_pair.shape = (2, 3, 30, 30)
Such that I can get the original images by slicing:
my_pair[0] == X
my_pair[1] == Y
After a few attempts, I keep getting either:
my_pair.shape = (2,) #By converting the images into lists and adding them.
This works as well, but the next step in the pipeline just requires a shape (2, 3, 30, 30)
my_pair.shape = (6, 30, 30) # using np.vstack
my_pair.shape = (3, 60, 30) # using np.hstack
Thanks!
Simply:
Z = np.array([X, Y])
Z.shape
Out[62]: (2, 3, 30, 30)

Categories

Resources