This question already has an answer here:
indexing spherical subset of 3d grid data in numpy
(1 answer)
Closed 9 years ago.
Can anybody help me - is there any way to create coordinates grid as numpy array like this?
(0,0) (0,1) (0,2) ... (0,n)
(1,0) (1,1) (1,2) ... (1,n)
...........................
(m,0) (m,1) (m,2) ... (m,n)
If yes, how can I find distance from every point to circle with center in (m/2, n/2) and radius R?
(x - m/2)^2 + (y - n/2)^2 - R^2 = ?
A standard way of doing this is with the meshgrid function. It makes two arrays, with the x and y coordinates of the points you want. To get the coordinates shown in your question you can do
import numpy as np
x = np.arange(m+1)
y = np.arange(n+1)
X, Y = np.meshgrid(x, y)
then to calculate the distance you want you can do
np.sqrt((X - m/2.)**2 + (Y - n/2.)**2) - R
For more information on meshgrid see the documentation
http://docs.scipy.org/doc/numpy/reference/generated/numpy.meshgrid.html
Also, if you want evenly spaced values between two endpoints instead of just 0 through m or 0 through n, consider using the linspace function.
Related
Let's say I have two arrays X and Y of floats (same length len) and a 2D array img (grayscale Image).
I want to calculate the values of img[X[i]][Y[i]] for i in {0..len} with a good approximation.
Is it enough to just convert X and Y to arrays of integers? Or is there a nice interpolation function that gives better results? (I looked for them but there are so many I got confused).
Thanks
import scipy.interpolate
y_interp = scipy.interpolate.interp1d(x, y)
print(y_interp(5.0))
scipy.interpolate.interp1d does linear interpolation by and can be customized to handle error conditions.
Just using python I would do something like this:
# Calculate tops (just in case the rounding goes over this)
x_top, y_top = len(img) - 1, len(img[0]) - 1
for x, y in zip(map(round, X), map(round, Y)):
x, y = min(x, x_top), min(y, y_top) # Check tops
val = img[x][y] # Here is your value
map(round, X) applies the function round to each element
zip takes to iterators and returns the elements in pairs
I have a time series of 3D vectors in a Python numpy array similar to the following:
array([[-0.062, -0.024, 1. ],
[-0.071, -0.03 , 0.98 ],
[-0.08 , -0.035, 0.991],
[-0.083, -0.035, 0.98 ],
[-0.083, -0.035, 0.977],
[-0.082, -0.035, 0.993],
[-0.08 , -0.034, 1.006],
[-0.081, -0.032, 1.008],
.......
I want to rotate each vector around a specified axis through a specified angle theta. I have been using quaternions to achieve this for one vector as found here in henneray's answer.
v1 = np.array ([1, -2, 0])
axis = np.array([-4, -2, 3])
theta = 1.5
rot_axis = np.insert(axis, 0, 0, axis=0)
axis_angle = (theta*0.5) * rot_axis/np.linalg.norm(rot_axis)
vec = quat.quaternion(*v1)
qlog = quat.quaternion(*axis_angle)
q = np.exp(qlog)
v_prime = q * vec * np.conjugate(q)
v_prime_vec = v_prime.imag
My question is, what is the fastest way to apply the same rotation to each vector in v1?
You cannot create a quaternion from v1 if v1 contains a 2D array of vectors, so I could use a loop to rotate each array element in turn; however, in henneray's answer in the link above, it is mentioned that the quaternions could be applied to 'appropriately vectorised numpy arrays'. Does anyone has any suggestions on how this could be implemented?
(A side question: if my theta and axis variables were arrays of equal length to v1, could the same method also be used to rotate each vector in v1 through a corresponding rotation?)
It is necessary to first convert the [x,y,z] Cartesian vectors into 4-vectors with the first component equal to zero [0,x,y,z]. Then you can cast this to a quaternion array to do vectorised calculations.
This function below takes an array of Cartesian vectors and rotates them about a single rotation axis. You will need to make sure the norm of this axis is equal to your rotation angle theta.
def rotate_vectors(vecs, axis):
"""
Rotate a list of 3D [x,y,z] vectors about corresponding 3D axis
[x,y,z] with norm equal to the rotation angle in radians
Parameters
----------
vectors : numpy.ndarray with shape [n,3]
list of [x,y,z] cartesian vector coordinates
axis : numpy.ndarray with shape [3]
[x,y,z] axis to rotate corresponding vectors about
"""
# Make an 4 x n array of zeros
vecs4 = np.zeros([vecs.shape[0],vecs.shape[1]+1])
# Fill the imaginary i, j, k components with x, y, z values, leaving the real part w=0
vecs4[:,1:] = vecs
# Convert to quaternion array
vecsq = quat.as_quat_array(vecs4)
# Make a rotation quaternion
qrot = quat.from_rotation_vector(axis)
# Rotate vectors
vecsq_rotated = qrot * vecsq * qrot.conjugate()
# Cast quaternion array to float and return only imaginary components (ignore real part)
return quat.as_float_array(vecsq_rotated)[:,1:]
As a bonus, this function takes an array of rotation axes to rotate each vector by the corresponding axes.
def rotate_vectors_each(vecs, axes):
"""
Rotate a list of 3D [x,y,z] vectors about corresponding 3D axes
[x,y,z] with norm equal to the rotation angle in radians
Parameters
----------
vectors : numpy.ndarray with shape [n,3]
list of [x,y,z] cartesian vector coordinates
axes : numpy.ndarray with shape [n,3]
axes to rotate corresponding vectors about
n = pulse shape time domain
3 = [x,y,z]
"""
# Make an 4 x n array of zeros
vecs4 = np.zeros([vecs.shape[0],vecs.shape[1]+1])
# Fill the imaginary i, j, k components with x, y, z values, leaving the real part w=0
vecs4[:,1:] = vecs
# Convert to quaternion array
vecsq = quat.as_quat_array(vecs4)
# Make an 4 x n array of zeros
rots4 = np.zeros([rots.shape[0],rots.shape[1]+1])
# Fill the imaginary i, j, k components with x, y, z values, leaving the real part w=0
rots4[:,1:] = rots
# Convert to quaternion array and take exponential
qrots = np.exp(quat.as_quat_array(0.5 * rots4))
# Rotate vectors
vecsq_rotated = qrots * vecsq * qrots.conjugate()
return quat.as_float_array(vecsq_rotated)[:,1:]
Note that with so many conversions between axis angle and quaternion representation, this will give you little performance improvement over rotation matrix algebra. Quaternions really only benefit when you are rotating a vector through many sequential rotations, whereby you can stack the quaternion multiplication.
One "fast" way to do the rotation calculation itself would be to turn your quaternion into a 3x3 direction cosine matrix, have your vectors in a single 3xN contiguous matrix, and then call a BLAS library routine (e.g., dgemm) to do a standard matrix multiply. A good BLAS library with large N would do this calculation multi-threaded.
This question already has answers here:
How can the Euclidean distance be calculated with NumPy?
(25 answers)
Closed 4 years ago.
I am trying to compute a vectorized implementation of Euclidean distance(between each element in X and Y using inner product). The data as follows:
X = np.random.uniform(low=0, high=1, size=(10000, 5))
Y = np.random.uniform(low=0, high=1, size=(10000, 5))
What I did was:
euclidean_distances_vectorized = np.array(np.sqrt(np.sum(X**2, axis=1) - 2 * np.dot(X, Y.T) + np.sum(Y**2, axis=1)))
Although this gives 'some output' the answer is wrong as each row still contains 5 elements.
Does anyone know what I am doing wrong?
If I understood correctly this should do
np.linalg.norm(X - Y, axis=1)
Or with einsum (square root of the dot product of each difference pair along the first axis)
np.sqrt(np.einsum('ij,ij->i...', X - Y, X - Y))
If you want all pairwise distances
from scipy.spatial.distance import cdist
cdist(X, Y)
This question already has answers here:
Why does pyplot.contour() require Z to be a 2D array?
(5 answers)
Closed 5 years ago.
I plot a contour plot which indicates the seperating hyperplane of a SVC estimator in a 2D axes using the following code.
X,y= make_circles(n_samples=50,factor=.1,noise=.1)
x_fit=np.linspace(-1.5,1.5,10)
y_fit=np.linspace(-1.5,1.5,10)
Y,XX=np.meshgrid(x_fit,y_fit)
xy=np.vstack([XX.ravel(),Y.ravel()]).T
P=clf.decision_function(xy).reshape(XX.shape)
plt.contour(XX,Y,P,colors="k",levels=[-1,0,1],alpha=0.5,linestyles=["--","-","--"])
Question
Based on this question and the answer of Ilya V. Schurov there is still one issue for me. I understand, that X and Y provides the x and y values and Z provides the "depth" for each xy coordiante and thus has to be 2 dimensional. Further, the X and Y values of the plt.contour() function can be either 1D or 2D (if 1D the meshgrid gets computed internally).
BUT what is the benefit/ reason for X and Y to be 2D?
Because actually the "second dimension" of X and Y can not be plotted on a 2D axes. So has it some "algorithmic performance" reasons for X and Y to be 2D or what is the reason?
Contour plot is not designed for just plotting hyperplanes for classfier. It represents a 3-D surface with a 2-D format; or it plots elevations of a 2-D area. Therefore, plt.contour() has to somehow understand/know elevations covering the whole area. One way, or the current way, is to provide a set of elevations for a set of points covering the 2-D area. And the more you provide, the better/finer the final contour plot is. When providing a 1-D x and y, it represents a line rather than an area, which cannot be used to interpolated a 2-D area.
Another way to plot hyperplanes is to calculate the exact planes yourself. Then you can plot hyperplanes with a 1-D linespace. But I don't think this will be easier than using plt.contour() since plt.contour() did the hard calculation by simulating with interpolation for you.
Edit: How Z works with X and Y in plt.contour()?
It takes some assumption for Z works with X and Y.
If X and Y is 2-D, a value in Z is the depth for a point specified by corresponding (same location by index) values in X and Y.
If X and Y is 1-D, it will be convert to a meshgrid first, as you can see in the source code. Then the rest will work the same way as explained above.
So for your case specifically, using x_fit and y_fit can give you the same result because plt.contour() makes the meshgrid for you. As long as you understand the mechanism, either way is fine. The only thing I would say is if you end up making the meshgrid for calculating P anyway, why not using the meshgrid to avoid assumption/ambiguity?
So I have a N-dimensional array of values, let's call it A. Now, I can plot this in a contour map, with coordinate axes X and Y, using
plt.contourf(X,Y,A)
Now, I have to carry out a mapping of these points to another plane, so, basically another set of coordinates. Let the transformation be
X - X1
Y - X1
Now, each point with magnitude "I" in matrix A at (X,Y) is at (X- X1, Y - Y1). I can plot this using
plt.contourf(X-X1, Y-Y1,A)
My question is, how do I index the array A such that I obtain an array B where the indexing corresponds to X-X1 and Y-Y1 instead of X and Y so that I can plot it directly using the following
plt.contourf(X,Y,B)
Thanks!