I have a bunch of arrays around 10,000~ 10000000. each containing coordinates points x,y,z. I have successfully stored those in Numpy array. i have generated maxi and mini using
np.array(np.amin(Vertex_combined[:,:,:],axis=1))
np.array(np.amax(Vertex_combined[:,:,:],axis=1))
these generate 2 ranges
maxs=array([[406.78, 805.73, 345.14],
[407.57, 805.83, 345.14],
[407.9 , 805.83, 314.19]])
mins=array([[405.05, 805.52, 314.15],
[405.84, 805.62, 314.15],
[406.78, 805.19, 309.75]])
Now I need to generate
np.mgrid[mins[1,0]:maxs[1,0]:0.5, mins[1,1]:maxs[1,1]:0.5].reshape(2,-1).T
array([[405.84, 805.62],
[406.34, 805.62],
[406.84, 805.62],
[407.34, 805.62]])
this works for single array by when i try
np.mgrid[mins[:,0]:maxs[:,0]:0.5, mins[:,1]:maxs[:,1]:0.5].reshape(2,-1).T
doesn't work. Any help or explanation for what I'm doing wrong would be of great help. thank you,
Traceback (most recent call last):
File "C:\Users\R414065\AppData\Local\Programs\Python\Python38\lib\site-packages\numpy\lib\index_tricks.py", line 164, in __getitem__
int(math.ceil((kk.stop - start) / (step * 1.0))))
TypeError: only size-1 arrays can be converted to Python scalars
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<pyshell#12>", line 1, in <module>
np.hstack(np.mgrid[mins[:,0]:maxs[:,0]:0.5, mins[:,2]:maxs[:,2]:0.5].reshape(2,-1).T)
File "C:\Users\R414065\AppData\Local\Programs\Python\Python38\lib\site-packages\numpy\lib\index_tricks.py", line 194, in __getitem__
step = key.step
AttributeError: 'tuple' object has no attribute 'step'
CodePudding user response:
As I wrote in the comments, mgrid
generates arange
(or its equivalent) for each 'dimension'. And that only works with scalar.
But lets look at the ranges that your bounds create:
In [53]: alist=[np.arange(x,y,.5) for x,y in zip(mins[:,0],maxs[:,0])]
In [54]: [x.shape for x in alist]
Out[54]: [(4,), (4,), (3,)]
In [55]: alist=[np.arange(x,y,.5) for x,y in zip(mins[:,1],maxs[:,1])]
In [56]: [x.shape for x in alist]
Out[56]: [(1,), (1,), (2,)]
Any time I see lists of arrays that differ in shape, I think - no way to avoid loops.
If we want the same number of elements for each range we can use linspace
:
In [57]: x = np.linspace(mins[:,0],maxs[:,0],4)
In [58]: y = np.linspace(mins[:,1],maxs[:,1],2)
In [59]: x
Out[59]:
array([[405.05 , 405.84 , 406.78 ],
[405.62666667, 406.41666667, 407.15333333],
[406.20333333, 406.99333333, 407.52666667],
[406.78 , 407.57 , 407.9 ]])
In [60]: y
Out[60]:
array([[805.52, 805.62, 805.19],
[805.73, 805.83, 805.83]])
As long as the number of elements in the range is the same, the difference between ranges is just a matter of scaling.
We can generate a mesh from these. It flattens them:
In [71]: I,J=np.meshgrid(x, y, indexing="ij")
In [72]: I.shape
Out[72]: (12, 6)
We could combine the earlier lists into one array:
In [73]: alist
Out[73]: [array([805.52]), array([805.62]), array([805.19, 805.69])]
In [74]: np.hstack(alist)
Out[74]: array([805.52, 805.62, 805.19, 805.69])
But I suspect you want to generate the individual meshes, and combine those, rather than combine the ranges first.
In short, you will need to iterate - unless I'm missing some nuance of what you are seeking.
edit
Here's the full iterative solution - which I think you should have shown, since it clarifies the problem:
Perform the individual mgrid
without the reshaping:
In [75]: alist = [
...: np.mgrid[mins[i, 0] : maxs[i, 0] : 0.5, mins[i, 1] : maxs[i, 1] : 0
...: .5]
...: for i in range(3)
...: ]
In [76]: alist
Out[76]:
[array([[[405.05],
[405.55],
[406.05],
[406.55]],
[[805.52],
[805.52],
[805.52],
[805.52]]]),
array([[[405.84],
[406.34],
[406.84],
[407.34]],
[[805.62],
[805.62],
[805.62],
[805.62]]]),
array([[[406.78, 406.78],
[407.28, 407.28],
[407.78, 407.78]],
[[805.19, 805.69],
[805.19, 805.69],
[805.19, 805.69]]])]
That highlights how different each grid is. They still differ when reshaped:
In [77]: blist = [x.reshape(2, -1).T for x in alist]
In [78]: blist
Out[78]:
[array([[405.05, 805.52],
[405.55, 805.52],
[406.05, 805.52],
[406.55, 805.52]]),
array([[405.84, 805.62],
[406.34, 805.62],
[406.84, 805.62],
[407.34, 805.62]]),
array([[406.78, 805.19],
[406.78, 805.69],
[407.28, 805.19],
[407.28, 805.69],
[407.78, 805.19],
[407.78, 805.69]])]
They could be joined into one (n,2) array:
In [79]: np.vstack(blist)
Out[79]:
array([[405.05, 805.52],
[405.55, 805.52],
[406.05, 805.52],
[406.55, 805.52],
[405.84, 805.62],
[406.34, 805.62],
[406.84, 805.62],
[407.34, 805.62],
[406.78, 805.19],
[406.78, 805.69],
[407.28, 805.19],
[407.28, 805.69],
[407.78, 805.19],
[407.78, 805.69]])