Stacked numpy arrays - python

I am considerably new to Python.I am willing to stack a few 1-d arrays in python and create a 2-d array using that. The arrays which I want to stack are returned from another function. The minimum reproducible code that I have written for this purpose has been shown below:
def fun1(i): # this function returns the array
return array # This array is a function of i
h0= np.empty(5,dtype=object)
arrays=[h0]
for i in range(4):
arr=fun1(i)
arrays.append(arr)
h=np.vstack(arrays)
print (h)
The desired output is of the form :
[[1 1 1 1 1]
[2 2 2 2 2]
[3 3 3 3 3]
[4 4 4 4 4]]
But I get :
[[None None None None None]
[1 1 1 1 1]
[2 2 2 2 2]
[3 3 3 3 3]
[4 4 4 4 4]]
I understand that I get the above output because an empty array of dtype=object has all elements None . But I am not being able to solve the problem. Any help regarding this would be highly appreciated.

You are getting None because you are creating an empty array with dtype object:
h0 = np.empty(5,dtype=object)
This line creates an array with None elements.
You can remove this line so that it works as you expect:
def fun1(i): # this function returns the array
return array # This array is a function of i
arrays=[]
for i in range(4):
arr=fun1(i)
arrays.append(arr)
h = np.vstack(arrays)
print (h)

if np.where(~a.any(axis=1))[0]:
#do nothing
else:
#print as you like

try this
h = np.vstack([
fun1(i)
for i in range(4)
])
print(h)
^^ this is assuming that fun1() is some proprietary function returning arrays of same length
but if you want a 2D array with equal rows entries and incrementing column-wise like
[[1 1 1 1 1]
[2 2 2 2 2]
[3 3 3 3 3]
[4 4 4 4 4]]
you can also try a faster method
x = np.arange(1,5).reshape([-1,1])
h = np.repeat(x, 5, axis= 1)

Related

Modify order of column in a 2D numpy array

I'm working with a 2D numpy array like this:
array = np.asarray([[1,1,1,1,1],
[2,2,2,2,2],
[3,3,3,3,3],
[4,4,4,4,4],
[5,5,5,5,5]])
I also have a 1D containing indexes to change the order of the columns of my first array.
So with this index array:
column_order = np.asarray([3,2,1,0,4])
I should have someting like this:
[[4 4 4 4 4]
[3 3 3 3 3]
[2 2 2 2 2]
[1 1 1 1 1]
[5 5 5 5 5]]
This is my code:
array = np.asarray([[1,1,1,1,1],
[2,2,2,2,2],
[3,3,3,3,3],
[4,4,4,4,4],
[5,5,5,5,5]])
column_order = np.asarray([3,2,1,0,4])
new_array = np.copy(array)
for idx , i in enumerate(column_order):
new_array[i] = array[idx]
print(new_array)
The problem is that it is a bit slow on large size array.
I would like to know if there is most efficient way to do this ?

Problem with understanding of work of np.argpartition

I have problem with execution of np.argpartition
I have nd.array
example = np.array([[5,6,7,3,4],[1,2,3,7,5],[6,7,4,2,3],[1,2,3,5,9],[2,3,6,1,2,]])
out: [[5 6 7 3 4]
[1 2 3 7 5]
[6 7 4 2 3]
[1 2 3 5 9]
[2 3 6 1 2]]
I can get indices for sorted array by np.argsort
print(np.argsort(example))
out:
[[3 4 0 1 2]
[0 1 2 4 3]
[3 4 2 0 1]
[0 1 2 3 4]
[3 0 4 1 2]]
I want to use np.argsort to economy some time for executing, because I need only 3 sorted element in each row of this array. I use this code to do it:
print(np.argpartition(example, 3, axis=1))
out: [[3 4 0 1 2]
[1 0 2 4 3]
[3 4 2 0 1]
[1 0 2 3 4]
[3 4 0 1 2]]
I expect that the first three indices of each row will match the indices in the sorted array, but this is not the caseю That doesn't work . I don't understand what I did wrong.
np.argpartition(example, k, axis=1) does not return sorted array for first k elements. It only returns indices such that only (k+1)th element is sorted. If you see in your output, only the 4th element matches with argsort()
If you want first three sorted elements, you have to give a list for k parameter
index_array = np.argpartition(example, [0,1,2], axis=1)
print(np.take_along_axis(example,index_array, axis=1)) ##this will give you first 3 sorted elements

Storing "n" number of 2D matrices into a single 3D matrix [duplicate]

This question already has answers here:
Concatenate two NumPy arrays vertically
(5 answers)
Closed 1 year ago.
I have "n" number of 2D matrices of same size. I want to store all these 2D matrices one by one into a single 3D numpy matrix/array.
Can anyone please tell me how to do this in python?
You can use numpy.dstack() such as:
import numpy as np
a = np.array([[1,2,3],[1,2,3]])
b = np.array([[2,3,4],[2,3,4]])
c = np.array([[3,4,5],[3,4,5]])
new_3d = np.dstack((a,b,c))
Output:
[[[1 2 3]
[2 3 4]
[3 4 5]]
[[1 2 3]
[2 3 4]
[3 4 5]]]
Update for new question:
Also, you can add another 2d again and again like:
d = np.array([[3,4,5],[3,4,5]])
new_3d = np.dstack((new_3d,d))
Output:
[[[1 2 3 3]
[2 3 4 4]
[3 4 5 5]]
[[1 2 3 3]
[2 3 4 4]
[3 4 5 5]]]

Numpy: value substitution according to neighbours

I need to change value for items in a numpy array on the basis of their neighbours values.
More specifically, let's suppose that I have just 3 possible values for each item in a numpy representing an image. Let's suppose my numpy is the following one:
[[1,1,1,1,1,1,1],
[1,1,1,1,1,1,1],
[1,1,1,2,1,1,1],
[1,1,1,2,1,1,1],
[1,1,1,1,1,1,1],
[3,3,3,3,3,3,3],
[3,3,3,3,3,3,3],
[3,3,3,3,3,3,3]
]
What I want is:
Since the size of group of contiguous items containing the value 2 in such example is less than (3 x 3) matrix, I need to assign them the value of neighbour items: in such case 1!
Resulting numpy has to be
[[1,1,1,1,1,1,1],
[1,1,1,1,1,1,1],
[1,1,1,**1**,1,1,1],
[1,1,1,**1**,1,1,1],
[1,1,1,1,1,1,1],
[3,3,3,3,3,3,3],
[3,3,3,3,3,3,3],
[3,3,3,3,3,3,3]
]
What I would like to have is that the 'spurious' elements (only two cells containing the value 2 in an area with a predominance of 1 values) are eliminated and uniformed to the area in which they appear. I hope I have explained. Thanks for any information you can give me. Thanks a lot.
In image processing this operations are called morphological filtering. In your case you can use an opening.
import numpy as np
from skimage.morphology.grey import opening
from skimage.morphology import square
a = np.array(
[[1,1,1,1,1,1,1],
[1,1,1,1,1,1,1],
[1,1,1,2,1,1,1],
[1,1,1,2,1,1,1],
[1,1,1,1,1,1,1],
[3,3,3,3,3,3,3],
[3,3,3,3,3,3,3],
[3,3,3,3,3,3,3]
])
opening(a, square(3))
Out:
[[1 1 1 1 1 1 1]
[1 1 1 1 1 1 1]
[1 1 1 1 1 1 1]
[1 1 1 1 1 1 1]
[1 1 1 1 1 1 1]
[3 3 3 3 3 3 3]
[3 3 3 3 3 3 3]
[3 3 3 3 3 3 3]]

How to overwrite 2-D numpy multi times symmetrically with given index?

I'm trying to change values in matrix a with given index matrix d and matrix e.
And the matrix should always be symmetrical.
What I come up with is to overwrite the primal matrix with given index, and try to make it symmetrical, then go for another overwrite, until all the given index matrix have been gone through. It's not efficient.
But I'm stuck with how make it symmetrical.
For example:
a = np.ones([4,4],dtype=np.object) #the primal matrix
d = np.array([[1],
[2],
[0],
[0]]) #the first index matrix
a[np.arange(a.shape[0])[:,None],d] =2 #the element change to 2 with the indexes shown in d matrix
Now the result is:
a = np.array([[1 2 1 1]
[1 1 2 1]
[2 1 1 1]
[2 1 1 1]])
After making it symmetrical (if a[ i ][ j ] was selected in d matrix, a[ j ][ i ] should also be changed to 2, how to do this part).
The expected output should be :
a = np.array([[1 2 2 2]
[2 1 2 1]
[2 2 1 1]
[2 1 1 1]])
Then, for another overwrite again:
e = np.array([[0],[2],[1],[1]])
a[np.arange(a.shape[0])[:,None],e] =3
Now the result is:
a = np.array([[3 2 2 2]
[2 1 3 1]
[2 3 1 1]
[2 3 1 1]])
Make it symmetrical, (I don't know how to do this part) the final output should be : (overwrite the values if they were given 2 or 1 before)
a = np.array([[3 2 2 2]
[2 1 3 3]
[2 3 1 1]
[2 3 1 1]])
What should I do to get symmetrical matrix?
And, is there anyway to change the primal matrix a directly to get the final result? In a more efficient way?
Thanks in advance !!
You can simply switch the first and second indices and apply the change, the result would be symmetrical:
a[np.arange(a.shape[0])[:,None], d] = 2
a[d, np.arange(a.shape[0])[:,None]] = 2
output:
[[1 2 2 2]
[2 1 2 1]
[2 2 1 1]
[2 1 1 1]]
Same with any number of other changes:
a[np.arange(a.shape[0])[:,None], e] = 3
a[e, np.arange(a.shape[0])[:,None]] = 3
output:
[[3 2 2 2]
[2 1 3 3]
[2 3 1 1]
[2 3 1 1]]

Categories

Resources