简体   繁体   中英

convert python operations to numpy

I wrote a basic code which accepts two point coordinates, derives the eqaution of the line passing through it and of the perpendicular, then outputs two points which are the edges of the same perpendicular line. My aim is to do something like what is shown in the pictures of this answer , but without all those third-party packages, and without a GIS.

Now, talking about performance, I think my code could greatly benefit of the numpy package, especially in view of using this calculations in a loop with lots (even millions) of pair of point coordinates. Since I didn't use numpy so much, can anyone:

  1. (confirm that adapting the code to use numpy would enhance the performance)
  2. suggest of should I adapt the code (eg some good hint to start)?

Here is the code, hope someone would find it useful ( matplotlib is there just to visualize the result).

import matplotlib.pyplot as plt

# calculate y from X coord, slope and intercept
def calculate_y(x, m, q):
    y = m * x + q
    return y

# the two point coordinates
point_A = [5,7] # First considered point
point_B = [4,10] # Second considered point

# calculate the slope between the point pair
m = (point_A[1] - point_B[1]) / (point_A[0] - point_B[0])

# calculate slope and intercept of the perpendicular (using the second original point)
m_perp = -(1/m)
q_perp = point_B[1] - m_perp * point_B[0]
##print "Perpendicular Line is y = {m}x + {q}".format(m=m_perp,q=q_perp)

# calculate corods of the perpendicular line
distance_factor = 1 #distance from central point
min_X = point_B[0] - distance_factor # left-side X
min_Y = calculate_y(min_X, m_perp, q_perp) # left-side Y

max_X = point_B[0] + distance_factor # right-side X
max_Y = calculate_y(max_X, m_perp, q_perp) # right-side Y

perp_A = (min_X, min_Y)
perp_B = (max_X, max_Y)

x_coord, y_coord = zip(*[point_A, point_B])
x_perp_coord, y_perp_coord = zip(*[perp_A, perp_B])

plt.scatter(x_coord, y_coord)
plt.scatter(x_perp_coord, y_perp_coord)
plt.show()

1) Yes, numpy would increase the performance a lot. Instead of doing a loop in python, you have it in C using the vectorization of numpy.

2) ideas:

import matplotlib.pyplot as plt
import numpy as np

# get random coords
npts = 10
distance_factor = 0.05
points = (np.sort(np.random.random(2*npts)).reshape((npts,2)) \
         + np.random.random((npts,2))/npts).T
points_x = points[0]  # vector of the chain of x coords
points_y = points[1]  # vector of the chain of y coords
plt.plot(points_x, points_y, 'k-o')
plt.gca().set_aspect('equal')
points_x_center = (points_x[1:] + points_x[:-1])*0.5
points_y_center = (points_y[1:] + points_y[:-1])*0.5
plt.plot(points_x_center, points_y_center, 'bo')
ang = np.arctan2(np.diff(points_y), np.diff(points_x)) + np.pi*0.5
min_X = points_x_center + distance_factor*np.cos(ang)
min_Y = points_y_center + distance_factor*np.sin(ang)
max_X = points_x_center - distance_factor*np.cos(ang)
max_Y = points_y_center - distance_factor*np.sin(ang)
plt.plot(np.vstack((min_X,max_X)), np.vstack((min_Y,max_Y)), 'r-')
plt.plot(np.vstack((min_X,max_X)).T, np.vstack((min_Y,max_Y)).T, 'r-', lw=2)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM