I'm trying to add a border (filled with 0's) around an existing array.
My code:
a = np.random.random((4, 5))
m, n = a.shape
b = np.zeros((m+1, n+1))
b[1:-1,1:-1] = a
a,b
but I got a error:
ValueError: could not broadcast input array from shape (4,5) into shape (3,4)
Why can't I directly assign values to parts of a 2D numpy array? where is the problem?
You can accomplish your task using np.pad function:
b = np.pad(a, 1)
Shorter code than yours.
Read the documentation of this function for any details.
b[:, [0, -1]] = 0
b[[0, -1], :] = 0
Related
I am trying to get the dotproduct of two arrays in python using the numpy package. I get as output an array of size (n,). It says that my array has no column while I do see the results when I print it. Why does my array have no column and how do I fix this?
My goal is to calculate y - np.dot(x,b). The issue is that y is (124, 1) while np.dot(x,b) is (124,)
Thanks
It seems that you are trying to subtract two arrays of a different shape. Fortunately, it is off by a single additional axis, so there are two ways of handling it.
(1) You slice the y array to match the shape of the dot(x,b) array:
y = y[:,0]
print(y-np.dot(x,b))
(2) You add an additional axis on the np.dot(x,b) array:
dot = np.dot(x,b)
dot = dot[:,None]
print(y-dot)
Hope this helps
it may depends on the dimension of your array
For example :
a = [1, 0]
b = [[4, 1], [2, 2]]
c = np.dot(a,b)
gives
array([4, 1])
and its shape is (2,)
but if you change a like :
a = [[1, 0],[1,1]]
then result is :
array([[4, 1],
[6, 3]])
and its shape is (2,2)
I have two 3d np.arrays containing numbers.
both np.arrays can have different shapes (different dimensions).
my objective would be to generate a 3d np.array:
which have a shape which contain both other shapes (ie (1,1,3) & (1,2,1) => (1,2,3))
where each element is the sum of the element of the parent 3d array which have the same coordinates (assuming 0 when the coordinates did not exist)
to summarize, I would like to obtain the following:
a=np.array([[[0, 0, 0, 1]]])
b= np.array([[[0],
[1]]])
addition(a, b)
>>> array([[[0, 0, 0, 1],
[1, 0, 0, 0]]])
Thanks in advance for your help
EDIT: I found better
def addition(a,b):
c = np.zeros(np.max([np.shape(a), np.shape(b)], axis=0), dtype=int)
c[np.where(a!=0)] += a[np.where(a!=0)]
c[np.where(b!=0)] += b[np.where(b!=0)]
return c
OLD:
After multiple research, i haven’t found a good way to do it without
iterate over all of the array :
def addition(a, b):
c = np.zeros(np.max([np.shape(a), np.shape(b)], axis=0), dtype=int)
for index, element in np.ndenumerate(a):
c[index] += element
for index, element in np.ndenumerate(b):
c[index] += element
return c
I’ll continue to search a better way to do it
EDIT 2:
I added a dtype=int, because you seem to want to keep the int version instead of the float.
Have fun
I have a 3D numpy array A representing a batch of images:
A.shape -> (batch_size, height, width)
I want to access this array using two other arrays Hs,Ws, of size batch_size.
They contain the x index and y index of each image that I want to access.
Example 2 images of size 3x3:
A.shape(2,3,3)
A = [[[1,2,3],[5,6,7],[8,9,10]], [[10,20,30],[50,60,70],[80,90,100]]]
Hs = [0,2]
Ws = [1,2]
I want to acces A so that I get:
A[:, Hs,Ws] = [2,100]
Doing it like this (A[:, Hs,Ws]) unfortunately results in a 2x2 array (batch_size x batch_size)
Executed with a for loop this would look like this:
Result = np.zeros(batch_size)
for b in range(0,batch_size):
Result[b] = A[b,Hs[b],Ws[b]]
Is it possible to do this without a for loop by accessing A directly in a vectorized manner?
Do you mean this:
In [6]: A = np.array(A); Hs=np.array(Hs); Ws=np.array(Ws)
In [7]: A.shape
Out[7]: (2, 3, 3)
In [8]: A[np.arange(2), Hs, Ws]
Out[8]: array([ 2, 100])
When using indexing arrays, they 'broadcast' against each other. Here with (2,),(2,),(2,) the broadcasting is eash.
I tried this:
import numpy as np
a = np.empty((1, 10, 1), np.int8)
a[0] = range(10)
It throw error: ValueError: could not broadcast input array from shape (10) into shape (10,1)
Several options that work in this case:
a[0, :, 0] = np.arange(10) # assign to 1D slice
a[0].flat = range(10) # assign to flattened 2D slice
a[0] = np.arange(10).reshape(10, 1) # bring the rigth side into correct shape
a[0] = np.arange(10)[:, np.newaxis] # bring the rigth side into correct shape
Note the use of np.arange instead of range. The former directly creates an ndarray with a sequence of values, while the latter creates an iterable that needs to be converted into an array for the assignment.
In the case of assigning to flat it makes sense to use range because both are iterators.
You can do a[0, :, 0] = range(10).
I want to convert a 1-dimensional array into a 2-dimensional array by specifying the number of columns in the 2D array. Something that would work like this:
> import numpy as np
> A = np.array([1,2,3,4,5,6])
> B = vec2matrix(A,ncol=2)
> B
array([[1, 2],
[3, 4],
[5, 6]])
Does numpy have a function that works like my made-up function "vec2matrix"? (I understand that you can index a 1D array like a 2D array, but that isn't an option in the code I have - I need to make this conversion.)
You want to reshape the array.
B = np.reshape(A, (-1, 2))
where -1 infers the size of the new dimension from the size of the input array.
You have two options:
If you no longer want the original shape, the easiest is just to assign a new shape to the array
a.shape = (a.size//ncols, ncols)
You can switch the a.size//ncols by -1 to compute the proper shape automatically. Make sure that a.shape[0]*a.shape[1]=a.size, else you'll run into some problem.
You can get a new array with the np.reshape function, that works mostly like the version presented above
new = np.reshape(a, (-1, ncols))
When it's possible, new will be just a view of the initial array a, meaning that the data are shared. In some cases, though, new array will be acopy instead. Note that np.reshape also accepts an optional keyword order that lets you switch from row-major C order to column-major Fortran order. np.reshape is the function version of the a.reshape method.
If you can't respect the requirement a.shape[0]*a.shape[1]=a.size, you're stuck with having to create a new array. You can use the np.resize function and mixing it with np.reshape, such as
>>> a =np.arange(9)
>>> np.resize(a, 10).reshape(5,2)
Try something like:
B = np.reshape(A,(-1,ncols))
You'll need to make sure that you can divide the number of elements in your array by ncols though. You can also play with the order in which the numbers are pulled into B using the order keyword.
If your sole purpose is to convert a 1d array X to a 2d array just do:
X = np.reshape(X,(1, X.size))
convert a 1-dimensional array into a 2-dimensional array by adding new axis.
a=np.array([10,20,30,40,50,60])
b=a[:,np.newaxis]--it will convert it to two dimension.
There is a simple way as well, we can use the reshape function in a different way:
A_reshape = A.reshape(No_of_rows, No_of_columns)
You can useflatten() from the numpy package.
import numpy as np
a = np.array([[1, 2],
[3, 4],
[5, 6]])
a_flat = a.flatten()
print(f"original array: {a} \nflattened array = {a_flat}")
Output:
original array: [[1 2]
[3 4]
[5 6]]
flattened array = [1 2 3 4 5 6]
some_array.shape = (1,)+some_array.shape
or get a new one
another_array = numpy.reshape(some_array, (1,)+some_array.shape)
This will make dimensions +1, equals to adding a bracket on the outermost
Change 1D array into 2D array without using Numpy.
l = [i for i in range(1,21)]
part = 3
new = []
start, end = 0, part
while end <= len(l):
temp = []
for i in range(start, end):
temp.append(l[i])
new.append(temp)
start += part
end += part
print("new values: ", new)
# for uneven cases
temp = []
while start < len(l):
temp.append(l[start])
start += 1
new.append(temp)
print("new values for uneven cases: ", new)
import numpy as np
array = np.arange(8)
print("Original array : \n", array)
array = np.arange(8).reshape(2, 4)
print("New array : \n", array)