5

I have the following DataFrame converted into GeoDataFrame:

import pandas as pd
import geopandas as gpd
data = {
 'lat':[-34.661412, -38.700402],
 'lng':[-58.366424, -62.294023],
 'buffer_value':[1000000000000,100000000000]
 }
df = pd.DataFrame(data)
gdf = gpd.GeoDataFrame(df, geometry=gpd.points_from_xy(far.lng, far.lat))

I want to create a buffer based on "buffer_value" distance which is different for each column.

Using:

gdf['buffer_0'] = gdf.buffer(10, resolution=16)

creates the same distance buffer for all rows, and not different buffers for each row.

I tried the following two different alternatives:

gdf['buffer_1'] = gdf.apply(lambda row: row.geometry.buffer(row.buffer_value, resolution=16), axis=1)

and

def buffer(row):
 return row.geometry.buffer(row.buffer_value)
gdf['buffer_2'] = gdf.apply(buffer, axis=1)

But both alternatives create an object column, not a geometry column.

<class 'geopandas.geodataframe.GeoDataFrame'>
RangeIndex: 2 entries, 0 to 1
Data columns (total 7 columns):
 # Column Non-Null Count Dtype 
--- ------ -------------- ----- 
 0 lat 2 non-null float64 
 1 lng 2 non-null float64 
 2 buffer_value 2 non-null int64 
 3 geometry 2 non-null geometry
 4 buffer_1 2 non-null object 
 5 buffer_2 2 non-null object 
 6 buffer_0 2 non-null geometry
dtypes: float64(2), geometry(2), int64(1), object(2)
memory usage: 240.0+ bytes

What am I doing wrong?

Taras
35.7k5 gold badges77 silver badges151 bronze badges
asked Jun 3, 2021 at 19:14

2 Answers 2

4

Here you go:

import pandas as pd
import geopandas as gpd
# dataframe
data = {
 'lat':[-34.661412, -38.700402],
 'lng':[-58.366424, -62.294023],
 'buffer_value':[1000000000000,100000000000]
 }
df = pd.DataFrame(data)
gdf = gpd.GeoDataFrame(df, geometry=gpd.points_from_xy(df['lng'], df['lat']))
# buffering
gdf['buffer'] = gdf.buffer(gdf['buffer_value'], resolution=16)
# show data
gdf.head()
gdf.dtypes
gdf['buffer'].plot(facecolor="none", edgecolor="black")

enter image description here

answered Jun 3, 2021 at 21:09
2
  • This is the correct answer. buffer is a vectorized function and using apply or loop will have a significant impact on performance. Commented Jun 4, 2021 at 8:37
  • Works great! Thanks! Commented Jun 4, 2021 at 12:37
2

You can use the custom function below called make_variable_buffer. Here is a small reproducible example.

import geopandas as gpd
def make_variable_buffer(input_df, 
 buffer_size_col_name, 
 geometry_column_name='geometry'):
 '''
 Creates a new GeoDataFrame whose geometries are the result of generating 
 variable-sized buffers from the input geometries. 
 
 Parameters
 ----------
 input_df : gpd.GeoDataFrame
 Input dataframe. The function will generate a copy of this dataframe 
 and the geometry of each row of this new dataframe will be a buffered 
 version of the geometries in the input dataframe
 buffer_size_col_name : str
 Name of the column of the input_df that contains the sizes/magnitudes 
 of the variable buffer. Please note that this measure is in the same 
 unit as your input features' CRS. 
 geometry_column_name : str
 Name of the column of the input_df that contains the geometries
 The default is 'geometry'.
 Returns
 -------
 buff_df : gpd.GeoDataFrame
 Dataframe that contains the buffers of varying sizes.
 '''
 
 # Copying the input_df
 buff_df = input_df.copy()
 
 # Creating the varying-sized buffer
 buff_df['geometry'] = input_df.apply(lambda row: 
 (row[geometry_column_name]
 .buffer(row[buffer_size_col_name])),
 axis=1)
 
 # Returning the newly-created dataframe
 return buff_df
data = {'lat':[-34.661412, -38.700402],
 'lng':[-58.366424, -62.294023],
 'buffer_value':[1,0.3]}
df = gpd.GeoDataFrame(data, 
 geometry=gpd.points_from_xy(data['lng'], 
 data['lat']), 
 crs='epsg:4326')
buff_df = make_variable_buffer(input_df=df, 
 buffer_size_col_name='buffer_value',
 geometry_column_name='geometry')
buff_df.plot()

This yields two different buffer sizes:

varying buffer sizes

answered Jun 3, 2021 at 21:41

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.