Reputation: 53
I'm trying to calculate initial and subsequent distances between points. The data I was given is a csv where every three columns corresponds to an LED marker. ie column 1 is the x-coord for marker 1, column 2 is the y-coord for marker 1, column 3 is the z-coord for marker 1 ets. each row corresponds to the time at which the location was recorded. I'm having a difficult time figuring out the best way to organize the data so that I can use it. I need to a) find initial locations and initial distances between markers at time 0 and b)find any change in distance between markers at different times.
I originally put all x-coords in an array, all y-coords in an array and all z-coords in an array, but realized that I couldn't (didn't know how?) to iterate over arrays so I could find the difference between the adjacent points. ie. the distance between marker 1 and marker 2 is sqrt((x2-x1)**2+(y2-y1)**2+(z2-z1)**2) but since x2 and x1 are in the same array couldn't (didn't know how?) to iterate the difference between all xs (and ys and zs, respectively). In the code below I transposed the arrays so I could iterate over rows (not columns)
for i in range(m): #where m is the number of markers
x_diff= x_array[i+1]-x_array[i]
y_diff=y_array[i+1]-y_array[i]
z_diff=z_array[i+1]-z_array[i]
dist=np.sqrt(x_diff**2+y_diff**2+z_diff**2)
I'd like an array where each column is the euclidean distance between adjacent markers and the rows correspond to the distance at each time.
Upvotes: 2
Views: 1230
Reputation: 1878
You can use SciPy's pdist function for pairwise distances. For example,
>>> X
array([[1, 2, 3],
[1, 2, 3],
[4, 0, 0]])
>>> from scipy.spatial.distance import pdist
>>> pdist(X)
array([0. , 4.69041576, 4.69041576])
The distances are output as pairs (0,1), (0,2), (1,2).
Upvotes: 2
Reputation: 14399
You need to turn that 2d array into a 3d array.
rows, cols = csv.shape
csv_3d = csv.reshape(rows, -1, 3)
Then np.diff
along the second axis (between points)
del_csv_3d = np.diff(csv_3d, axis = 1)
Then take the norm along the last axis
out = np.linalg.norm(del_csv_3d , axis = -1)
This should be the data you need.
Upvotes: 0
Reputation: 53029
Here is a step-by-step starting from an array that is layed out like your original csv:
# 2 time points, 4 markers, values between 0 and 8
csv = np.random.randint(0,9,(2,12))
csv
# array([[8, 5, 3, 2, 3, 2, 2, 5, 6, 8, 2, 4],
# [8, 2, 7, 4, 7, 7, 8, 0, 3, 0, 2, 4]])
# reshape to get x,y,z aligned
m,n = csv.shape
xyz = csv.reshape(m,-1,3)
xyz
# array([[[8, 5, 3],
# [2, 3, 2],
# [2, 5, 6],
# [8, 2, 4]],
#
# [[8, 2, 7],
# [4, 7, 7],
# [8, 0, 3],
# [0, 2, 4]]])
# get coordinate-wise differences between adjacent markers
dist_1d = np.diff(xyz,axis=1)
dist_1d
# array([[[-6, -2, -1],
# [ 0, 2, 4],
# [ 6, -3, -2]],
#
# [[-4, 5, 0],
# [ 4, -7, -4],
# [-8, 2, 1]]])
# compute squared Euclidean distance
# (you could take the square root of that but if you are
# only interested in changes it doesn't seem necessary)
eucl2 = (dist_1d*dist_1d).sum(axis=2)
eucl2
# array([[41, 20, 49],
# [41, 81, 69]])
Upvotes: 0