Ayuda a que mi código sea más rápido: Mi código python necesita generar un enrejado 2D de puntos que caen dentro de un rectángulo delimitador. Arreglé un código (que se muestra a continuación) que genera este enrejado. Sin embargo, esta función se llama muchas veces y se ha convertido en un serio cuello de botella en mi aplicación.Genere de manera eficiente un enrejado de puntos en python
Estoy seguro de que hay una forma más rápida de hacerlo, probablemente con matrices numpy en lugar de listas. ¿Alguna sugerencia para una forma más rápida y más elegante de hacer esto?
Descripción de la función: Tengo dos vectores 2D, v1 y v2. Estos vectores define a lattice. En mi caso, mis vectores definen una retícula que es casi, pero no del todo, hexagonal. Quiero generar el conjunto de todos los puntos 2D en este enrejado que están en algún rectángulo delimitador. En mi caso, una de las esquinas del rectángulo está en (0, 0), y las otras esquinas están en coordenadas positivas.
Ejemplo: Si la esquina más alejada de mi rectángulo delimitador estaba en (3, 3), y mis vectores de la red fueron:
v1 = (1.2, 0.1)
v2 = (0.2, 1.1)
me gustaría que mi función para devolver los puntos:
(1.2, 0.1) #v1
(2.4, 0.2) #2*v1
(0.2, 1.1) #v2
(0.4, 2.2) #2*v2
(1.4, 1.2) #v1 + v2
(2.6, 1.3) #2*v1 + v2
(1.6, 2.3) #v1 + 2*v2
(2.8, 2.4) #2*v1 + 2*v2
No me preocupan los casos extremos; no importa si la función retorna (0, 0), por ejemplo.
La forma más lenta Actualmente lo estoy haciendo:
import numpy, pylab
def generate_lattice(#Help me speed up this function, please!
image_shape, lattice_vectors, center_pix='image', edge_buffer=2):
##Preprocessing. Not much of a bottleneck:
if center_pix == 'image':
center_pix = numpy.array(image_shape) // 2
else: ##Express the center pixel in terms of the lattice vectors
center_pix = numpy.array(center_pix) - (numpy.array(image_shape) // 2)
lattice_components = numpy.linalg.solve(
numpy.vstack(lattice_vectors[:2]).T,
center_pix)
lattice_components -= lattice_components // 1
center_pix = (lattice_vectors[0] * lattice_components[0] +
lattice_vectors[1] * lattice_components[1] +
numpy.array(image_shape)//2)
num_vectors = int(##Estimate how many lattice points we need
max(image_shape)/numpy.sqrt(lattice_vectors[0]**2).sum())
lattice_points = []
lower_bounds = numpy.array((edge_buffer, edge_buffer))
upper_bounds = numpy.array(image_shape) - edge_buffer
##SLOW LOOP HERE. 'num_vectors' is often quite large.
for i in range(-num_vectors, num_vectors):
for j in range(-num_vectors, num_vectors):
lp = i * lattice_vectors[0] + j * lattice_vectors[1] + center_pix
if all(lower_bounds < lp) and all(lp < upper_bounds):
lattice_points.append(lp)
return lattice_points
##Test the function and display the output.
##No optimization needed past this point.
lattice_vectors = [
numpy.array([-40., -1.]),
numpy.array([ 18., -37.])]
image_shape = (1000, 1000)
spots = generate_lattice(image_shape, lattice_vectors)
fig=pylab.figure()
pylab.plot([p[1] for p in spots], [p[0] for p in spots], '.')
pylab.axis('equal')
fig.show()
¿Sería mejor para usted hacer 'lattice_components = numpy.modf (lattice_components) [0]'? (No pregunta por su pregunta, pero solo por curiosidad. ¿Sería significativamente más rápido/más lento?) – JAB
No sabía nada sobre modf, buena sugerencia. Creo que la mayor parte del tiempo dedicado a esta función está dentro del bucle for anidado doble, pero haré un benchmark para asegurarme. – Andrew
por favor, escriba un resumen de lo que hace esta función. –