Paddin new axis in 3d matrix returns error

Question:

What I need to do is to extend a 2D matrix to 3D and fill the 3rd axis with an arbitrary number of zero. The error returned is:

all the input arrays must have same number of dimensions, but the
array at index 0 has 3 dimension(s) and the array at index 1 has 0
dimension(s)

What should I correct?

import numpy as np

kernel = np.ones((3,3)) / 9
kernel = kernel[..., None]
print(type(kernel))

print(np.shape(kernel))
print(kernel)

i = 1
for i in range(27):
    np.append(kernel, 0, axis = 2)

print(kernel)
Asked By: levgor

||

Answers:

What should I use instead of np.append()?

Use concatenate():

import numpy as np

kernel = np.ones((3,3)) / 9
kernel = kernel[..., None]
print(type(kernel))

print(np.shape(kernel))
print(kernel)
print('-----------------------------')

append_values = np.zeros((3,3))
append_values = append_values[..., None]
i = 1
for i in range(2):
    kernel = np.concatenate((kernel, append_values), axis=2)

print(kernel.shape)
print(kernel)

But best generate the append_values array already with the required shape in the third dimension to avoid looping:

append_values = np.zeros((3,3,2)) # or (3,3,27)
kernel = np.concatenate((kernel, append_values), axis=2)
print(kernel.shape)
print(kernel)
Answered By: Claudio

Look at the output and error – full error, not just a piece!

<class 'numpy.ndarray'>
(3, 3, 1)
...

In [94]: np.append(kernel, 0, axis = 2)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Input In [94], in <cell line: 1>()
----> 1 np.append(kernel, 0, axis = 2)

File <__array_function__ internals>:5, in append(*args, **kwargs)

File ~anaconda3libsite-packagesnumpylibfunction_base.py:4817, in append(arr, values, axis)
   4815     values = ravel(values)
   4816     axis = arr.ndim-1
-> 4817 return concatenate((arr, values), axis=axis)

File <__array_function__ internals>:5, in concatenate(*args, **kwargs)

ValueError: all the input arrays must have same number of dimensions, but the array at index 0 has 3 dimension(s) and the array at index 1 has 0 dimension(s)

As your shape shows kernel is 3d (3,3,1). np.append takes the scalar 0, and makes an array, np.array(0), and calls concatenate. concatenate, if you take time to read its docs, requires matching numbers of dimensions.

But my main beef with your code was that you used np.append without capturing the result. Again, if you take time to read the docs, you’ll realize that np.append does not work in-place. It does NOT modify kernel. When it works, it returns a new array. And doing that repeatedly in a loop is inefficient.

It looks like you took the list append model, applied it without much thought, to arrays. That’s not how to code numpy.

As the other answer shows, doing one concatenate with a (3,3,27) array of 0s is the way to go if you want to make a (3,3,28) array.

Alternatively make a (3,3,28) array of 0s, and copy the one (3,3,1) array to the appropriate column.

Answered By: hpaulj
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.