the output of using np.empty_like in Python - python

While studying the NumPy package of Python, I tried the following code segment
import numpy as np
x = np.array([[1,2,3],[4,5,6],[7,8,9],[10,11,12]])
v = np.array([1,0,1])
y = np.empty_like(x)
print(y)
for i in range(4):
y[i,:] = x[i,:]+v
print "......."
print(y)
However, the first print(y) gives the output such as following, instead of all zero array. On the other side, the second print(y)generates the correct result as expected. I would like to know why.
[[ 72 0 0]
[ 0 2676 1346720256]
[1599357253 1950699087 10]
[1346524499 1163154497 242503250]]
.......
[[ 2 2 4]
[ 5 5 7]
[ 8 8 10]
[11 11 13]]

You want zeros_like. empty_like gives an array filled with who-knows-what, so it doesn't have to spend time filling it with zeros.

Related

How to construct a simple matrix and change values according to equation (numpy)?

My question is really simple. I have to make a 5*5 matrix and each i,j value should follow a formula of i+j
I have this so far:
'''
w = np.zeros(shape=(5,5))
print(w)
for i in range(5):
for j in range(5):
w[i][j] == i**2+j
print(w)
But Its just returning a 0 matrix right now what to do ?
Just change
w[i][j] == i**2+j
to (if you want to keep the formular)
w[i,j] = i**2+j
or use the formular from your question
w[i,j] = i+j
If you want to get rid of the loops, you can use numpy
w = np.arange(5)
w = np.add.outer(w ** 2, w)
print(w)
Out:
[[ 0 1 2 3 4]
[ 1 2 3 4 5]
[ 4 5 6 7 8]
[ 9 10 11 12 13]
[16 17 18 19 20]]

Is there a numpy function that mimics A[[i,j],...][...,[a,b,c]] but is not read only?

I am trying to do some matrix calculations with numpy and some sparse matrices. For that I want to ignore the zeros in my matrix and just access some values, but I also need to overwrite them.
import numpy as np
a=np.random.rand(5,5)
#does not change a:
a[[1,2],...][...,[1,2]]=np.array([[0,0],[0,0]])
#just changes (1,1) and (2,2)
a[[1,2],[1,2]]=np.array([0,0])
I would like to overwrite [1,1],[1,2],[2,1],[2,2] with zeros.
I think you need something like this:
import numpy as np
a = np.arange(25).reshape((5, 5))
i, j = np.ix_([1, 2], [1, 2])
a[i, j] = np.zeros((2, 2))
print(a)
# [[ 0 1 2 3 4]
# [ 5 0 0 8 9]
# [10 0 0 13 14]
# [15 16 17 18 19]
# [20 21 22 23 24]]
One general way for any given list of indices could be to simply loop over your index pairs where you want to assign 0
import numpy as np
a=np.random.rand(5,5)
indices = [[1,1],[1,2],[2,1],[2,2] ]
for i in indices:
a[tuple(i)] = 0
print (a)
array([[0.16014178, 0.68771817, 0.97822325, 0.30983165, 0.60145224],
[0.10440995, 0. , 0. , 0.09527387, 0.38472278],
[0.93199524, 0. , 0. , 0.11230965, 0.81220929],
[0.91941358, 0.96513491, 0.07891327, 0.43564498, 0.43580541],
[0.94158242, 0.78145344, 0.73241028, 0.35964791, 0.62645245]])

stacking numpy arrays?

I am trying to stack arrays horizontally, using numpy hstack, but can't get it to work. Instead, it all comes out in one list, instead of a 'matrix-looking' 2D array.
import numpy as np
y = np.array([0,2,-6,4,1])
y_bool = y > 0
y_bool = [1 if l == True else 0 for l in y_bool] #convert to decimals for classification
y_range = range(0,len(y))
print y
print y_bool
print y_range
print np.hstack((y,y_bool,y_range))
Prints this:
[ 0 2 -6 4 1]
[0, 1, 0, 1, 1]
[0, 1, 2, 3, 4]
[ 0 2 -6 4 1 0 1 0 1 1 0 1 2 3 4]
How do I instead get the last line to look like this:
[0 0 0
2 1 1
-6 0 2
4 1 3]
If you want to create a 2D array, do:
print np.transpose(np.array((y, y_bool, y_range)))
# [[ 0 0 0]
# [ 2 1 1]
# [-6 0 2]
# [ 4 1 3]
# [ 1 1 4]]
Well, close enough h is for horizontal/column wise, if you check its help, you will see under See Also
vstack : Stack arrays in sequence vertically (row wise).
dstack : Stack arrays in sequence depth wise (along third axis).
concatenate : Join a sequence of arrays together.
Edit: First thought vstack does it, but it would be if np.vstack(...).T or np.dstack(...).squeeze(). Other then that the "problem" is that the arrays are 1D and you want them to act like 2D, so you could do:
print np.hstack([np.asarray(a)[:,np.newaxis] for a in (y,y_bool,y_range)])
the np.asarray is there just in case one of the variables is a list. The np.newaxis makes them 2D to make it clearer what happens when concatenating.

Numpy fancy indexing in multiple dimensions

Let's say I have an numpy array A of size n x m x k and another array B of size n x m that has indices from 1 to k.
I want to access each n x m slice of A using the index given at this place in B,
giving me an array of size n x m.
Edit: that is apparently not what I want!
[[ I can achieve this using take like this:
A.take(B)
]] end edit
Can this be achieved using fancy indexing?
I would have thought A[B] would give the same result, but that results
in an array of size n x m x m x k (which I don't really understand).
The reason I don't want to use take is that I want to be able to assign this portion something, like
A[B] = 1
The only working solution that I have so far is
A.reshape(-1, k)[np.arange(n * m), B.ravel()].reshape(n, m)
but surely there has to be an easier way?
Suppose
import numpy as np
np.random.seed(0)
n,m,k = 2,3,5
A = np.arange(n*m*k,0,-1).reshape((n,m,k))
print(A)
# [[[30 29 28 27 26]
# [25 24 23 22 21]
# [20 19 18 17 16]]
# [[15 14 13 12 11]
# [10 9 8 7 6]
# [ 5 4 3 2 1]]]
B = np.random.randint(k, size=(n,m))
print(B)
# [[4 0 3]
# [3 3 1]]
To create this array,
print(A.reshape(-1, k)[np.arange(n * m), B.ravel()])
# [26 25 17 12 7 4]
as a nxm array using fancy indexing:
i,j = np.ogrid[0:n, 0:m]
print(A[i, j, B])
# [[26 25 17]
# [12 7 4]]

Slicing at runtime

can someone explain me how to slice a numpy.array at runtime?
I don't know the rank (number of dimensions) at 'coding time'.
A minimal example:
import numpy as np
a = np.arange(16).reshape(4,4) # 2D matrix
targetsize = [2,3] # desired shape
b_correct = dynSlicing(a, targetsize)
b_wrong = np.resize(a, targetsize)
print a
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[12 13 14 15]]
print b_correct
[[0 1 2]
[4 5 6]]
print b_wrong
[[0 1 2]
[3 4 5]]
And my ugly dynSlicing():
def dynSlicing(data, targetsize):
ndims = len(targetsize)
if(ndims==1):
return data[:targetsize[0]],
elif(ndims==2):
return data[:targetsize[0], :targetsize[1]]
elif(ndims==3):
return data[:targetsize[0], :targetsize[1], :targetsize[2]]
elif(ndims==4):
return data[:targetsize[0], :targetsize[1], :targetsize[2], :targetsize[3]]
Resize() will not do the job since it flats the array before dropping elements.
Thanks,
Tebas
Passing a tuple of slice objects does the job:
def dynSlicing(data, targetsize):
return data[tuple(slice(x) for x in targetsize)]
Simple solution:
b = a[tuple(map(slice,targetsize))]
You can directly 'change' it. This is due to the nature of arrays only allowing backdrop.
Instead you can copy a section, or even better create a view of the desired shape:
Link

Categories