1
\$\begingroup\$

I'm working in a function that generates isochrones for a project of mine and I'm facing a bottleneck performing some distance calculations.

Here is what I'm doing:

def distanciapunto(row, punto):
    try:
        geometriarow = transform(transformer.transform, row["geometry"])
        geometriapunto = transform(transformer.transform, punto)
        distancia = geometriarow.distance(geometriapunto)
        return distancia
    except AttributeError:
        return 10000
dfinterno["distancia"] = dfinterno.apply(lambda row: distanciapunto(row, p), axis=1)

Is there a way to make this faster?

Minimal reproducible example:

from shapely.geometry import Point, LineString
from functools import partial
import pyproj
from shapely.ops import transform
import pandas as pd

def distanciapunto(row, punto, transformer):
    try:
        geometriarow = transform(transformer, row["geometry"])
        geometriapunto = transform(transformer, punto)
        distancia = geometriarow.distance(geometriapunto)
        return distancia
    except AttributeError:
        return 10000

dfinterno = pd.DataFrame({
    "geometry": [LineString([(0, 0), (3, 4)]), LineString([(2, 2), (5, 6)]), LineString([(1, 1), (4, 5)])]
})
transformer = partial(pyproj.transform, pyproj.Proj(init='EPSG:4326'), pyproj.Proj(init='EPSG:22185'))
p = Point(1, 1)    
dfinterno["distancia"] = dfinterno.apply(lambda row: distanciapunto(row, p, transformer), axis=1)

print(dfinterno["distancia"])
\$\endgroup\$
1
  • 2
    \$\begingroup\$ Rather than returning a magic number I would really like to see INFINITE_DISTANCE = 10_000 defined. And pep-8 asks that you spell it distancia_punto, geometria_row, and so on. But you were mostly interested in performance. Thank you kindly for the MRE, that really is quite helpful. Perhaps you'd like to expand it so it crunches for ten seconds and then gives a performance metric? \$\endgroup\$
    – J_H
    Jul 5, 2023 at 3:11

1 Answer 1

1
\$\begingroup\$

General (non-) review:

  • Don't run words together like that in identifiers. PEP-8 says you should use underscores as word separators; e.g. distancia_punto rather than distanciapunto.
  • The function's docstring is missing. It needs to describe the meaning of the arguments, and also the global variable (transformer) that is referenced.
  • Prefer to pass transformer as an argument rather than using a global variable.
  • Choose a better exceptional return (10 000 metres is a plausible distance between two points on Earth; 50 000 is impossible; None clearly distinguishes from an actual value). Better, don't catch the exception and instead allow the caller to decide what should happen.
  • The final line (outside the function) references another global into which I have no insight.
\$\endgroup\$
1
  • \$\begingroup\$ Thanks @greybeard - that's a constant hazard of switching between languages. \$\endgroup\$ Jul 6, 2023 at 9:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.