3D numpy array in Theano - python

I'm having a 3D NumpyArray which I want to through in a Keras Neural Network.
Because of one hot encoding the array became a 3D array.
[
[[0,1,0,0], [1,0,0,0]],
[[0,0,0,1], [1,1,0,0]],
[[0,0,1,0], [0,0,0,1]]
]
Since Keras can only compute 2D arrays, my question is, how can I reduce the dimensionality and use it into a sequencial keras NN?
I currently get the error:
TypeError: ('Bad input argument to theano function with name "D:\\Python27\\lib\\site-packages\\keras\\backend\\theano_backend.py:503" at index 0(0-based)', 'Wrong number of dimensions: expected 2, got 3 with shape (32L, 10L, 12L).')

You can use numpy.ndarray.flatten to make it into a 1D array. Example:
import numpy as np
a = np.array(
[
[[0, 1, 0, 0], [1, 0, 0, 0]],
[[0, 0, 0, 1], [1, 1, 0, 0]],
[[0, 0, 1, 0], [0, 0, 0, 1]]
]
)
a.flatten()
From this, if you want to split it by row, I'd recommend doing
import numpy as np
a = np.array(
[
[[0, 1, 0, 0], [1, 0, 0, 0]],
[[0, 0, 0, 1], [1, 1, 0, 0]],
[[0, 0, 1, 0], [0, 0, 0, 1]]
]
)
a = map(np.ndarray.flatten, a)

Related

Convert a 2D numpy array into a hot-encoded 3D numpy array, with same values in the same plane

Suppose I have a Numpy array:
[
[0, 1, 0],
[0, 1, 4],
[2, 0, 0],
]
How can I turn this into a "hot encoded" 3D array? something like this:
[
# Group of 0's
[[1, 0, 1],
[1, 0, 0],
[0, 1, 1]],
# Group of 1's
[[0, 1, 0],
[0, 1, 0],
[0, 0, 0]],
# Group of 2's
[[0, 0, 0],
[0, 0, 0],
[1, 0, 0]],
# Group of 3's
# the group is still here, even though there are no threes
[[0, 0, 0],
[0, 0, 0],
[0, 0, 0]],
# Group of 4's
[[0, 0, 0],
[0, 0, 1],
[0, 0, 0]]
]
That is, how can I take each occurrence of a number in the array and "group" them into their own plane in a 3D matrix? As shown in the example, even the "gap" in numbers (i.e. the 3) should still appear. In my case, I know the range of the data beforehand (range (0, 6]), so that should make it easier.
BTW, I need this because I have a chessboard represented by numbers, but need it in this form to pass into a 2d convolutional neural network (different "channels" for different pieces).
I've seen Convert a 2d matrix to a 3d one hot matrix numpy, but that has a one-hot encoding for every value, which isn't what I'm looking for.
Create the desired array (arr.max()+1 here) and then reshape it to compare to the original array:
Setup:
arr = np.array([
[0, 1, 0],
[0, 1, 4],
[2, 0, 0],
])
u = np.arange(arr.max()+1)
(u[:,np.newaxis,np.newaxis]==arr).astype(int)
array([[[1, 0, 1],
[1, 0, 0],
[0, 1, 1]],
[[0, 1, 0],
[0, 1, 0],
[0, 0, 0]],
[[0, 0, 0],
[0, 0, 0],
[1, 0, 0]],
[[0, 0, 0],
[0, 0, 0],
[0, 0, 0]],
[[0, 0, 0],
[0, 0, 1],
[0, 0, 0]]])

Numpy assignment of 3D array values using 2D index array

I have a 3D numpy array of zeros, with dimensions CxHxW (in this example, C=4, H=2, and W=3):
A = np.array([[[0, 0, 0],
[0, 0, 0]],
[[0, 0, 0],
[0, 0, 0]]
[[0, 0, 0],
[0, 0, 0]]
[[0, 0, 0],
[0, 0, 0]]])
I also have a 2D array of indices, with dimensions HxW, such that every value in the array is a valid index between [0, C-1]
B = np.array([[2, 3, 0],
[3, 1, 2]])
Is there a fast way, using vectorization, to modify array A such that A[B[i][j]][i][j] = 1, for all valid i, j?
A = np.array([[[0, 0, 1],
[0, 0, 0]],
[[0, 0, 0],
[0, 1, 0]]
[[1, 0, 0],
[0, 0, 1]]
[[0, 1, 0],
[1, 0, 0]]])
Thank you!
It seems like you are looking for put_along_axis:
np.put_along_axis(A, B[None,...], 1, 0)
Note that the second argument is required to have the same number of dimensions as the first, which is why B[None,...] is used instead of B.

Multiply all pairs of rows in a Numpy array [duplicate]

This question already has an answer here:
How to compute the outer product of two matrices in numpy?
(1 answer)
Closed 4 years ago.
I have an MxN Numpy array. I'd like to take each row of the array and multiply it element-wise by each row of the array, resulting in an MxMxN numpy array of the products.
le_input = np.array([
[0, 0, 1],
[0, 1, 0]
])
le_expected_output = np.array([
[
[0, 0, 1],
[0, 0, 0]
],
[
[0, 0, 0],
[0, 1, 0]
]
])
I can of course do this with a for loop, and I've tried that, but I'm assuming there's a way faster way to do this within Numpy. Does anyone have any ideas?
You can use np.einsum:
np.einsum('ik,jk->ijk', le_input, le_input)
# array([[[0, 0, 1],
# [0, 0, 0]],
# [[0, 0, 0],
# [0, 1, 0]]])
Or create a new axis and use array's broadcasting property to calculate the outer product on the first dimension:
le_input[:,None] * le_input
# array([[[0, 0, 1],
# [0, 0, 0]],
# [[0, 0, 0],
# [0, 1, 0]]])

One-Hot Encoding without for-loop from vector of positions in Python with NumPy?

I have some data that I want to "one-hot encode" and it is represented as a 1-dimensional vector of positions.
Is there any function in NumPy that can expand my x into my x_ohe?
I'm trying to avoid using for-loops in Python at all costs for operations like this after watching Jake Vanderplas's talk
x = np.asarray([0,0,1,0,2])
x_ohe = np.zeros((len(x), 3), dtype=int)
for i, pos in enumerate(x):
x_ohe[i,pos] = 1
x_ohe
# array([[1, 0, 0],
# [1, 0, 0],
# [0, 1, 0],
# [1, 0, 0],
# [0, 0, 1]])
If x only contains non negative integers, you can compare x with a sequence use numpy broadcasting and convert the result to ints:
(x[:,None] == np.arange(x.max()+1)).astype(int)
#array([[1, 0, 0],
# [1, 0, 0],
# [0, 1, 0],
# [1, 0, 0],
# [0, 0, 1]])
Or initialize first, then assign ones use advanced indexing:
x_ohe = np.zeros((len(x), 3), dtype=int)
x_ohe[np.arange(len(x)), x] = 1
x_ohe
#array([[1, 0, 0],
# [1, 0, 0],
# [0, 1, 0],
# [1, 0, 0],
# [0, 0, 1]])
A one liner :
np.equal.outer(x,range(3)).astype(int)
array([[1, 0, 0],
[1, 0, 0],
[0, 1, 0],
[1, 0, 0],
[0, 0, 1]])
np.equal.outer(x,np.unique(x)).astype(int) works also here.

Circular convolution in python

Is there a way with Python to perform circular convolution between two 1D arrays,
like with Matlab function cconv?
I tried numpy.convolve but it isn't the same, and I can’t find an equivalent.
You can try this command : scipy.ndimage.filters.convolve1d
You have an option which is named modeand you can write mode = wrap
With that, you get periodic boundary conditions as padding for the convolution
For example :
result = scipy.ndimage.convolve(image,kernel,mode='wrap')
import numpy as np
image = np.array([[0, 0, 0, 0],
[0, 0, 0, 1],
[0, 0, 0, 0]])
kernel = np.array([[1, 1, 1],
[1, 1, 1],
[1, 1, 1]])
from scipy.ndimage import convolve
convolve(image, kernel, mode='wrap')
array([[1, 0, 1, 1],
[1, 0, 1, 1],
[1, 0, 1, 1]])

Categories

Resources