View function is not creating view correctly - python

I have created numpy array named a, then created another array b by view of a. Ex. b=a.view().
However, b.base is a is giving False instead of True. Please help.
a=np.arange(6).reshape(2,3)
b=a.view()
print(b.base is a) # Expected True, actual was False

Because it is a view of the original array which is returned by numpy.arange(6)
import numpy as np
a = np.arange(6)
b = a.reshape(2,3)
c = b.view()
print(c.base is a, b.base is a)

If you will use print statements,You will be very clear about this:-
import numpy as np
a=np.arange(6).reshape(2,3)
print(a)
b=a.view()
print(b.base)
The outputs of the print statements will look like
[[0 1 2]
[3 4 5]]
[0 1 2 3 4 5]
You can clearly see the difference.To make the output True you can use this:-
import numpy as np
a=np.arange(6)
newa=a.reshape(2,3)
print(a)
b=newa.view()
print(b.base)
print(b.base is a)
The Corresponding output will be:-
[0 1 2 3 4 5]
[0 1 2 3 4 5]
True

Related

Is np.argpartition giving me the wrong results?

Take the following code:
import numpy as np
one_dim = np.array([2, 3, 1, 5, 4])
partitioned = np.argpartition(one_dim, 0)
print(f'Unpartitioned array: {one_dim}')
print(f'Partitioned array index: {partitioned}')
print(f'Partitioned array: {one_dim[partitioned]}')
The following output results:
Unpartitioned array: [2 3 1 5 4]
Partitioned array index: [2 1 0 3 4]
Partitioned array: [1 3 2 5 4]
The output for the partitioned array should be [1 2 3 5 4]. How is three on the left side of two? It seems to me the function is making an error or am I missing something?
The second argument is which index will be in sorted position after partitioning, so it is correct that index 0 of the partition (element value 1) is in sorted position, and everything to the right is greater.

I have a 2d array. Need to make a loop to replace first 2 rows, then next 2 only rows and so on by ones and print till the loop ends

b = np.random.randint(0,10, (6,3))
I tried this code, but it gives the `ValueError: operands could not be broadcast together with shapes (2,3) () (6,3)
step = 2
r1 = 0
r2 = 2
while r2 <= len(b):
c = np.where(b[r1:r2] >= 0, 1, b)
print(c)
r1+ = step
r2+ = step
I think the problem is in a condition of np.where. It creates an array wih a shape that is incompatible with b array
What i need is for the code to receive array b and to return 3 arrays of the same size of b but with two rows been substituted by 1´s. Like this:
[[1 1 1]
[1 1 1]
[6 3 4]
[2 9 3]
[6 9 2]
[8 1 0]]
[[3 2 8]
[3 8 5]
[1 1 1]
[1 1 1]
[6 9 2]
[8 1 0]]
[[3 2 8]
[3 8 5]
[6 3 4]
[2 9 3]
[1 1 1]
[1 1 1]]
My tutor told me to try it with 'np.where' function.But it seems that this function doesnt support this type of condition i´m trying to feed to it. May be there is another way to get the desired output. All examples I googled work with random values of the array and not precisely rows. In pandas it easier. But i need numpy code to feed the output to the neural network. The ones will be treated by it as an empty values, but the size of the array will be always the same, thus not producing errors
You are getting a ValueError because the size of b[0:2] is not the same as the size of b.
print(b.shape)
# (6, 3)
print(b[0:2].shape)
# (2, 3)
The documentation for numpy.where states that the way the condition works is "Where True, yield x, otherwise yield y." Thus, you need to be able to broadcast x and y onto the size of your condition. In your example, you can't broadcast (6,3) onto (2,3) and hence the error.
You need things to be the same size. For example, c = np.where(b[0:2] >= 0, 1, b[0:2]) would not give you an error.
However, if you want to step through your array b, then you need something other than b[0:2]. Otherwise it will just keep repeating that first part your array. I think you probably want b[r1:r2].
Also, I notice that you have r1+ = step instead of r1 += step, which will also spit out an error. Note that you don't actually need both r1 and r2 since their offset is step.
Putting all this together, we can adjust your code to give you something that works:
import numpy as np
b = np.random.randint(0,5, (6,3))
step = 2
r1 = 0
while r1 <= len(b) - step:
c = np.copy(b)
c[r1:r1+step] = np.where(b[r1:r1+step] >= 0, 1, b[r1:r1+step])
print(c)
r1 += step
Or you could instead do it with a for loop instead of a while loop:
import numpy as np
b = np.random.randint(0,5, (6,3))
step = 2
for r1 in range(0, len(b), step):
c = np.copy(b)
c[r1:r1+step] = np.where(b[r1:r1+step] >= 0, 1, b[r1:r1+step])
print(c)
Resulting output:
[[1 1 1]
[1 1 1]
[3 2 2]
[1 1 2]
[3 3 0]
[3 2 2]]
[[4 0 2]
[4 0 0]
[1 1 1]
[1 1 1]
[3 3 0]
[3 2 2]]
[[4 0 2]
[4 0 0]
[3 2 2]
[1 1 2]
[1 1 1]
[1 1 1]]

replace element by element different arrays

I have an array :
a = np.array([1,2,3,4,5,6,7,8])
The array may be reshaped to a = np.array([[1,2,3,4],[5,6,7,8]]), whatever is more convenient.
Now, I have an array :
b = np.array([[11,22,33,44], [55,66,77,88]])
I want to replace to each of these elements the corresponding elements from a.
The a array will always hold as many elements as b has.
So, array b will be :
[1,2,3,4], [5,6,7,8]
Note, that I must keep each b subarray dimension to (4,). I don't want to change it.So, the idx will take values from 0 to 3.I want to make a fit to every four values.
I am struggling with reshape, split,mask ..etc and I can't figure a way to do it.
import numpy as np
#a = np.array([[1,2,3,4],[5,6,7,8]])
a = np.array([1,2,3,4,5,6,7,8])
b = np.array([[11,22,33,44], [55,66,77,88]])
for arr in b:
for idx, x in enumerate(arr):
replace every arr[idx] with corresponding a value
For your current case, what you want is probably:
b, c = list(a.reshape(2, -1))
This isn't the cleanest, but it is a one-liner. Turn your 1D array into a 2D array with with the first dimension as 2 with reshape(2, -1), then list splits it along the first dimension so you can directly assign them to b, c
You can also do it with the specialty function numpy.split
b, c = np.split(a, 2)
EDIT: Based on accepted solution, vectorized way to do this is
b = a.reshape(b.shape)
The following worked for me:
i = 0
for arr in b:
for idx, x in enumerate(arr):
arr[idx] = a[i]
print(arr[idx])
i += 1
Output (arr[idx]): 1 2 3 4 5 6 7 8
If you type print(b) it'll output [[1 2 3 4] [5 6 7 8]]
b = a[:len(a)//2]
c = a[len(a)//2:]
Well, I'm quite new to Python but this worked for me:
for i in range (0, len(a)//2):
b[i] = a[i]
for i in range (len(a)//2,len(a)):
c[i-4] = a[i]
by printing the 3 arrays I have the following output:
[1 2 3 4 5 6 7 8]
[1 2 3 4]
[5 6 7 8]
But I would go for Daniel's solution (the split one): 1 liner, using numpy API, ...

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.

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