1

Is there a good way to read CSVs that contain a WKT column straight into a GeoPandas GeoDataFrame?

I've seen several solutions that take a two-step approach:

  1. Read the CSV into a Pandas DataFrame
  2. Pass the DataFrame to GeoPandas and use shapely.wkt.loads() to generate the actual geometries

I'm trying to avoid this two-step process and find a way to do this in one single step. However, the approach I use feels a little dirty and I just wanted to see if there's a better/more efficient way to do it. Here is a reproducible example where both approaches are showcased:

Reproducible example

# Loading libraries needed
import shapely
import pandas as pd
import geopandas as gpd

# Making mock CSV file
csv_filename = 'temp.csv'

(pd.DataFrame(data={"ids":[1,2,3],
                    "wkt_geom":['POINT (1 1)',
                                'POINT (2 2)',
                                'POINT (3 3)']})
 .to_csv(csv_filename, index=False))

# Two-step approach
df = pd.read_csv(csv_filename)

gdf = gpd.GeoDataFrame(data=df, 
                       geometry=df['wkt_geom']
                       .apply(shapely.wkt.loads))

# One-step approach
gdf = (gpd.read_file(csv_filename)
       .assign(geometry=lambda _df: shapely.wkt.loads(_df['wkt_geom']))
       .set_geometry('geometry'))

Streamlining the one-step approach

The one-step approach I showed above feels a little janky: it relies on the assign command and then requires me to use the set_geometry command.

Is there a more direct way we can read a CSV file containing a WKT column straight into a GeoPandas GeoDataFrame in such a way that the WKT column gets automatically parsed?

1 Answer 1

1

You can also use geopandas.GeoSeries.from_wkt:

df = pd.read_csv(csv_filename)
print(df)
    ids     wkt_geom
0    1  POINT (1 1)
1    2  POINT (2 2)
2    3  POINT (3 3)



s = gpd.GeoSeries.from_wkt(df.wkt_geom)
gdf = gpd.GeoDataFrame(data=df, geometry=s)
print(gdf)
     ids     wkt_geom          geometry
 0    1  POINT (1 1)  POINT (1.00000 1.00000)
 1    2  POINT (2 2)  POINT (2.00000 2.00000)
 2    3  POINT (3 3)  POINT (3.00000 3.00000)
3
  • Oh yeah, I forgot about the from_wkt method! This is great, thank you!!! I see that your solution takes the multi-step approach here of loading the CSV into a DF and then using that DF to make a GDF. Do you see a way of using a one-shot approach for that? The only solution I could think of also used the assign and set_geometry methods: gpd.read_file(csv_filename).assign(geom=lambda _df: gpd.GeoSeries.from_wkt(_df['wkt_geom'])).set_geometry('geom')
    – Felipe D.
    Commented Jul 14, 2023 at 19:13
  • Why do you want to use .assign
    – gene
    Commented Jul 15, 2023 at 13:19
  • Oh, sorry, I wasn't clear with my comment. I don't want to use assign. I just don't know how to perform a one-line process without using it. And my question in my last comment was geared towards: is it possible to do this in one step without the assign command? Sorry for the lack of clarity =)
    – Felipe D.
    Commented Jul 16, 2023 at 16:05

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.