I'm working with a 3d array of vectors, and having trouble reshaping properly.
My dimensions correspond to quantities as follows:
0 = vector (3)
1 = point (4)
2 = polyline (2)
So this can be interpreted as 2 polylines that each contain 4 points, and each point has a vector. I want to reshape to a 2d matrix that is (3, 8).
The original array is:
poly_array = array([[[-0.707, 0.0],
[-0.371, 0.0],
[0.371, 0.0],
[0.707, 0.0]],
[[0.0, -0.707],
[0.0, 0.0],
[0.0, 0.707],
[0.0, 0.0]],
[[0.707, 0.707],
[0.928, 1.0],
[0.928, 0.707],
[0.707, 0.0]]])
so if I'm looking at ordered points along the first polyline, I would run:
for i in range(4):
print poly_array[:,i,0]
or for ordered points along the second polyline:
for i in range(4):
print poly_array[:,i,1]
If I reshape this way:
new_dim = shape(poly_array)[1] * shape(poly_array)[2]
new_array = poly_array.reshape(3, new_dim)
But this orders the vectors as taking one from each polyline (i.e., pt0-polyline0, pt0-polyline1, pt1-polyline0, pt1-polyline1, etc.)
In: print new_array[:, 0]
Out: [-0.707 0. 0.707]
In: print new_array[:, 1]
Out: [ 0. -0.707 0.707]
But I want
In: print new_array[:, 1]
Out: [-0.371 0. 0.928]
How can I reshape so that it loops through all the vectors corresponding to points (along axis 1) for a given polyline before the next polyline?
You would need some permuting of axes with np.swapaxes and a reshape -
poly_array.swapaxes(1,2).reshape(poly_array.shape[0],-1)
Sample run -
In [127]: poly_array
Out[127]:
array([[[-0.707, 0. ],
[-0.371, 0. ],
[ 0.371, 0. ],
[ 0.707, 0. ]],
[[ 0. , -0.707],
[ 0. , 0. ],
[ 0. , 0.707],
[ 0. , 0. ]],
[[ 0.707, 0.707],
[ 0.928, 1. ],
[ 0.928, 0.707],
[ 0.707, 0. ]]])
In [142]: out
Out[142]:
array([[-0.707, -0.371, 0.371, 0.707, 0. , 0. , 0. , 0. ],
[ 0. , 0. , 0. , 0. , -0.707, 0. , 0.707, 0. ],
[ 0.707, 0.928, 0.928, 0.707, 0.707, 1. , 0.707, 0. ]])
In [143]: out[:,1]
Out[143]: array([-0.371, 0. , 0.928])
Related
I just want to sort of clarify for example could I somehow stack a few 2D arrays into an image?
array1=[[0,0,0,0,0]
[0,7.6,7,7.2,0]
[0,7.6,7,0,0]
[0,0,0,0,0]]
array2=[[0,0,0,0,0]
[0,7.6,7,7.2,0]
[0,7.6,7,0,0]
[0,0,0,0,0]]
And then see them in 3D space such as the cube example at link
I haven't really tried much other than trying to make other things using the geeks for geeks code. So any direction at all would be appreciated.
Assuming numpy arrays as input (not python lists), you can use numpy.dstack:
out = np.dstack((array1, array2))
output:
array([[[0. , 0. ],
[0. , 0. ],
[0. , 0. ],
[0. , 0. ],
[0. , 0. ]],
[[0. , 0. ],
[7.6, 7.6],
[7. , 7. ],
[7.2, 7.2],
[0. , 0. ]],
[[0. , 0. ],
[7.6, 7.6],
[7. , 7. ],
[0. , 0. ],
[0. , 0. ]],
[[0. , 0. ],
[0. , 0. ],
[0. , 0. ],
[0. , 0. ],
[0. , 0. ]]])
Although, if you want to plot, it might be easier to have a list of the arrays and loop.
I believe that you are looking for something like this. I am representing the depth dimension with different colors and an added depth of +z
A = np.array([ [*array1],[*array2] ])
ax = plt.axes(projection='3d')
z_c = ['k','blue']
[ax.scatter(z+A[z,y,x], y, x, c=z_c[z]) for z in range(A.shape[0]) \
for y in range(A.shape[1]) for x in range(A.shape[2])]
I am generating two parameters e.g.
s1 = [0, 0.25, 0.5, 0.75, 1.0]
s2 = [0, 0.25, 0.5, 0.75, 1.0]
based on dimensions of both these lists above, i am creating a grid of zeros:
np.zeros((5,5))
I then pair up each of the numbers in each list so they form coordinate locations in my empty grid e.g. (0,0), (0,0.25), (0,0.5) etc. (25 combinations to fit into 5x5 grid).
my issue is i am not too sure how to append values into the grid based on each of the coordinates generated. e.g. if i want to append the number 5 to grid location (0,0) etc so the grid fills up.
Any help is greatly appreciated.
The easiest way is probably to construct a meshgrid and transpose it so that the axises are the way you want them:
np.array(np.meshgrid(s1, s2)).transpose(1, 2, 0)
not sure it is fastest way to get it, check if the output is what you were expecting
import numpy as np
s1 = [0, 0.25, 0.5, 0.75, 1.0]
s2 = [0, 0.25, 0.5, 0.75, 1.0]
arr = np.zeros((5,5,2), dtype=float)
print (arr.shape, arr.size, arr.ndim)
for i in range(len(s1)):
for j in range(len(s2)):
arr[i,j] = s1[i], s2[j]
print(arr)
output :
(5, 5, 2) 50 3
[[[0. 0. ]
[0. 0.25]
[0. 0.5 ]
[0. 0.75]
[0. 1. ]]
[[0.25 0. ]
[0.25 0.25]
[0.25 0.5 ]
[0.25 0.75]
[0.25 1. ]]
[[0.5 0. ]
[0.5 0.25]
[0.5 0.5 ]
[0.5 0.75]
[0.5 1. ]]
[[0.75 0. ]
[0.75 0.25]
[0.75 0.5 ]
[0.75 0.75]
[0.75 1. ]]
[[1. 0. ]
[1. 0.25]
[1. 0.5 ]
[1. 0.75]
[1. 1. ]]]
I have a output called summation of the following form :
[[0.02719706]
[0.02851958]
[0.03727741]
[0.03857162]
[0.02222067]
[0.06348368]
[0.0179843 ]]
The output summation changes with loop j.
At each loop j, I am looking to store this result in a matrix MatrixDimension=np.zeros(( 7 , country ))
country=4
for j in range(country):
for i in range(7):
xxxxxxx
# code depends on j and i
xxxxxxx
summation[i]=np.sum(temp)
MatrixDimension[:, j]= summation ## where i have error
I get an error as follows
ValueError: could not broadcast input array from shape (7,1) into shape (7)
How can i fix this please?
Check whether summation is a 1-D array.
In this case the following code:
country = 4
MatrixDimension = np.zeros((7, country))
summation = np.array([1, 3, 5, 7, 9, 11, 13])
j = 0
MatrixDimension[:, j] = summation
print(MatrixDimension)
runs without any error and yields:
[[ 1. 0. 0. 0.]
[ 3. 0. 0. 0.]
[ 5. 0. 0. 0.]
[ 7. 0. 0. 0.]
[ 9. 0. 0. 0.]
[11. 0. 0. 0.]
[13. 0. 0. 0.]]
But if the source array is a column array, e.g.:
xx = np.array([1, 3, 5, 7, 9, 11, 13])[..., None]
then an attempt to execute e.g. MatrixDimension[:, 2] = xx
raises just the same exception which you mentioned, as
xx.shape is (7, 1), i.e. it is a 2-D array.
MatrixDimension[:, j:j+1] = summation
can put 2D array into the Matrix
I would like to compare values from columns of two different numpy arrays A and B. More specifically, A contains values from a real experiment that I want to match with theoretical values that are given in the third column of B.
There are no perfect matches and therefore I have to use a tolerance, e.g. 0.01. For each value in A, I expect 0 to 20 matches in B with respect to the selected tolerance. As a result, I would like to get those lines in B that are within the tolerance to a value in A.
To be more specific, here an example:
A = array([[ 2.83151742e+02, a0],
[ 2.83155339e+02, a1],
[ 3.29241719e+02, a2],
[ 3.29246229e+02, a3]])
B = array([[ 0, 0, 3.29235519e+02, ...],
[ 0, 0, 3.29240819e+02, ...],
[ 0, 0, 3.29241919e+02, ...],
[ 0, 0, 3.29242819e+02, ...]])
So here all values of B would match A[3,0] and A[4,0] for a tolerance of 0.02.
My preferred result would like this with the matched value of A in C[:,0] and the difference between C[:,0] and C[:,2] in C[:,1]:
C = array([[ 3.29241719e+02, c0, 3.29235519e+02, ...],
[ 3.29241719e+02, c1, 3.29240819e+02, ...],
[ 3.29241719e+02, c2, 3.29241919e+02, ...],
[ 3.29241719e+02, c3, 3.29242819e+02, ...]
[ 3.29242819e+02, c4, 3.29235519e+02, ...],
[ 3.29242819e+02, c5, 3.29240819e+02, ...],
[ 3.29242819e+02, c6, 3.29241919e+02, ...],
[ 3.29242819e+02, c7, 3.29242819e+02, ...]])
Typically, A has shape (500, 2) and B has shape (300000, 11). I can solve it with for-loops, yet it takes ages.
What would be the most efficient way for this comparison?
I'd imagine it would be something like
i = np.nonzero(np.isclose(A[:,:,None], B[:, 2]))[-1]
np.isclose accepts a few different tolerance parameters.
The values in B close to the A values would then be B[i, 2]
import numpy as np
X_mini=np.array([[ 4, 2104, 1],
[ 1, 1600, 3],
[ 3, 2400, 100]])
def feature_normalization(X):
row_length=len(X[0:1][0])
for i in range(0, row_length):
if not X[:,i].std()==0:
temp=(X[:,i]-X[:,i].mean())/X[:,i].std()
print(temp)
X[:,i]=temp
feature_normalization(X_mini)
print(X_mini)
outputs:
[ 1.06904497 -1.33630621 0.26726124]
[ 0.209937 -1.31614348 1.10620649]
[-0.72863911 -0.68535362 1.41399274]
[[ 1 0 0]
[-1 -1 0]
[ 0 1 1]]
my question is, why does not X_mini (after applying feature_normalization) correspond to what is being printed out?
Your array holds values of integer type (probably int64).
When fractions are inserted into it, they're converted to int.
You can explicitly specify the type of an array you create:
X_mini = np.array([[ 4.0, 2104.0, 1.0],
[ 1.0, 1600.0, 3.0],
[ 3.0, 2400.0, 100.0]], dtype=np.float128)
You can also convert an array to another type using numpy.ndarray.astype (docs).