5

I have a GeoDataFrame with 12.431 observations of geographical units, called "cities". I also have another layer file with points, called "points". Both of them are in CRS: EPSG4326.

I want to create a variable in the GeoDataFrame which indicates if it contains a point from the other file. This is done correctly from my code.

However, when I use len(df3) I obtained that my number of observations increase to 12.599. How is it possible? I have explored if I have missing values in any column but I do not find them.

Why the increase of 168 observations?

I need to maintain the same number of observations as in "cities".

This is the code I am using:

import numpy as np
import pandas as pd
import geopandas as gpd

df3 = gpd.sjoin(cities, points[['geometry']], how="left") 
df3['points'] = np.where(np.isnan(df3['index_right']), 0, 1)
 
del(df3['index_right'])

2 Answers 2

6

For each point inside a polygon, a new polygon will be created. So a polygon with 2 points in it will become two polygons in the output:

import geopandas as gpd

city = gpd.read_file(r"/home/bera/Desktop/GIStest/cities.shp")

#city.shape
#Out[2]: (3, 3)

# city.Name
# Out[9]: 
# 0    Manchester
# 1    Birmingham
# 2     Sheffield

pnt = gpd.read_file(r"/home/bera/Desktop/GIStest/pointsss.shp")
#pnt.shape
#Out[3]: (5, 2)

df3 = gpd.sjoin(city, pnt[['geometry']], how="left") 
#df3.shape
#Out[5]: (4, 4)


# df3.Name
# Out[10]: 
# 0    Manchester
# 0    Manchester
# 1    Birmingham
# 2     Sheffield

#Examples of what you can do to process the duplicates:

#df3.drop_duplicates(subset="Name", keep="first") #Delete them
#df3.groupby("Name").count() #Count

enter image description here

3
  • If I understood correctly, my layer "cities" has 168 observations with at least two points. When I apply my code, that observations are duplicated, right?
    – OgeiD
    Nov 4, 2022 at 9:39
  • 1
    If I use df3 = df3.drop_duplicates(subset="Name", keep="first"), it will remove the second observation, but my variable 'Points' will still maintain value 1 for the observation which is maintained in the geopanda. Is this also correct?
    – OgeiD
    Nov 4, 2022 at 9:44
  • 1
    To your first question: yes. Second: I'm not sure what you are asking. You probably want to .sort_values to make sure the dataframe is sorted in a way that the first observation is always the one you want to keep
    – BERA
    Nov 4, 2022 at 13:25
0

The accepted answer is correct. However, I would like to add that sjoin returns a dataframe of the objects that intersect with the geodataframe.

If there are two objects that intersecte, sjoin returns both objects.

Thus, if there are N points that lie within polygon (i.e. that intersect), all N will be returned in the output dataframe.

The method sjoin_nearest works in a similar way.

It makes sense to work this way, how would they choose which object to return if they had to return a single object?

New contributor
codeananda is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.

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.