# Calculate distance between points and price per area in Pandas

I'm trying to find distances between all points (latitude, longitude), and for each point, get the average price_area (price/area) of the closest points around it. This code is taking too long:

def create_pa_radius(df, radius):

for index, row in df.iterrows():
point = [row['latitude'], row['longitude']]
df['distances'] = df.apply(lambda x: geo_dist(point, [x['latitude'], x['longitude']]).km, axis = 1)
mean = samples.mean()

return df


I would like at least to understand how to make this kind of iteration faster.

• Welcome to Code Review! I changed the title to a different one that describes what the code does per site goals: "State what your code does in your title, not your main concerns about it.". Feel free to give it a different title if there is something more appropriate. – Sᴀᴍ Onᴇᴌᴀ Dec 6 '17 at 4:26
• This code as presented does not work. There is not radius defined. – Stephen Rauch Dec 6 '17 at 5:32
• Sorry, just fixed that. I'm new here, so let me know if I need to specify anything better for you to understand it. – Rodrigo Nader Dec 6 '17 at 6:32
• Hey could you include a sample dataframe? – Neil Dec 6 '17 at 7:00

The problem you are having is most likely due to your code being O(n²) on the size of your dataframe. (It's possible you have a small df and a really bad implementation of geo_dist, but I'll ignore that.)

Let's strip out most of your code:

for index, row in df.iterrows():
df['distances'] = df.apply(lambda x: geo_dist(point, [x['latitude'], x['longitude']]).km, axis = 1)


These lines can be rewritten:

for index, row in df.iterrows():
for i, r2 in df.iterrows():
p2 = (r2['latitude'], r2['longitude'])
df.distances[i] = geo_dist(point, *p2).km


The same is true for the filtering of distances < radius/1000: you are looping over all n rows, and then for each row you are looping over all n rows again. This is n * n operations, or O(n²).

There is no simple way to fix this. If you insist on computing the distances from each point to its surrounding points, you will have to structure your code this way. However, there are some alternatives:

1. You could use a kd-tree or a space partitioning hash of your own design to access your points. This would make pandas secondary in your access, requiring you to write more python code yourself.

• If your area is really small like that, try computing the maximum lat/long distance equal to that radius, then pre-filter the df using that distance: candidates = df[ center_lat - radius <= lat <= center_lat + radius]. This is still n² but it's a faster n² than the apply with python code. You can run that after you get your candidates, and it should be only on a subset, so much quicker. – Austin Hastings Dec 6 '17 at 19:43