【发布时间】:2023-03-19 06:49:02
【问题描述】:
我需要阅读大约。来自 PostGIS 数据库的 1000 万条记录到 GeoPandas 数据框中。直接从数据库中读取数据大约需要。 15 分钟通过以下方式:
geopandas.GeoDataFrame.from_postgis(sql, engine)
这是可以接受的,但我一直在尝试通过使用 PostgreSQL COPY 命令和 SQLAlchemy copy_export 函数来提高读取性能。使用这种方法将数据读取到 Pandas 数据帧中大约需要。 60 秒,这是一个巨大的进步:
def read_data(engine, sql):
with tempfile.TemporaryFile() as tmpFile:
copy_sql = "COPY ({query}) TO STDOUT WITH CSV {head}".format(
query=sql, head='HEADER'
)
con = engine.raw_connection()
cur = con.cursor()
cur.copy_expert(copy_sql, tmpFile)
tmpFile.seek(0)
df = pandas.read_csv(tmpFile)
return df
当尝试做同样的事情,但将数据读入 GeoPandas 数据框时,我遇到了与另一个进程正在使用的临时文件相关的问题:
def read_data(engine, sql):
with tempfile.NamedTemporaryFile(suffix='.csv') as tmpFile:
copy_sql = "COPY ({query}) TO STDOUT WITH CSV {head}".format(
query=sql, head='HEADER'
)
con = engine.raw_connection()
cur = con.cursor()
cur.copy_expert(copy_sql, tmpFile)
tmpFile.seek(0)
gdf = geopandas.read_file(tmpFile.name)
return gdf
fiona.errors.DriverError: C:\Temp\4\tmpiuu6dvl4.csv: file used by other process
我尝试了各种方法来释放临时文件上的锁定,但都没有成功,所以我又将数据读入 Pandas 数据帧,然后转换几何列。这可行,但与将数据直接从数据库读取到 GeoPandas 数据帧一样多:
def read_data(engine, sql):
with tempfile.TemporaryFile() as tmpFile:
copy_sql = "COPY ({query}) TO STDOUT WITH CSV {head}".format(
query=sql, head='HEADER'
)
con = engine.raw_connection()
cur = con.cursor()
cur.copy_expert(copy_sql, tmpFile)
tmpFile.seek(0)
df = pandas.read_csv(tmpFile)
df['geom'] = geopandas.GeoSeries.from_wkt(df['geom'])
return geopandas.GeoDataFrame(df, geometry='geom', crs='EPSG:3857')
需要很长时间的部分是从 WKT 到 GeoSeries 的转换:
df['geom'] = geopandas.GeoSeries.from_wkt(df['geom'])
有人知道解决锁定文件问题或加快从 WKT 到 GeoSeries 转换的解决方案吗?
谢谢
【问题讨论】:
-
你能提取几行你的csv文件吗?