У меня есть функция myfunc , которая принимает в качестве входных данных строку фрейма геоданных gpd_in и после некоторой обработки возвращает новый фрейм геоданных с несколькими строками. Как только функция myfunc применяется к каждой строке входного фрейма геоданных, все результирующие выходные фреймы геоданных объединяются для создания окончательного результата. Есть ли способ применить myfunc для параллельной обработки строк входного фрейма геоданных?
Пример:
import geopandas as gpd
def myfunc(row):
#some processing using different attributes of row and row.geometry
#resulting in the creation of list of geometries with their own attributes
gdf_new = gpd.GeoDataFrame(new_geom_list, columns=['geometry'], geometry='geometry', crs=crs)
gdf_new['Attr1'] = attr1_list
gdf_new['Attr2'] = attr2_list
return gdf_new
gpd_out = gpd.GeoDataFrame()
crs = gpd_in.crs
for row in gpd_in.itertuples():
gpd_out = gpd.pd.concat([gpd_out, myfunc(row)], ignore_index = True)
Можно ли запустить цикл for параллельно?
Сначала я пытался использовать .apply, но кажется, что .apply не будет работать, поскольку myfunc возвращает новый кадр геоданных вместо изменения значения в строке.
Я попробовал Parallel из joblib следующим образом:
results = Parallel(n_jobs=-1)(delayed(myfunc)(row) for row in gpd_in.itertuples())
но возникла следующая ошибка:
PicklingError: Could not pickle the task to send it to the workers.
РЕДАКТИРОВАНИЕ: предоставление рабочего примера согласно комментарию @Timeless
import numpy as np
import rasterio
from rasterio.transform import from_origin
import geopandas as gpd
import os
work_folder = r"define/your/work/folder"
## CREATING INPUT DATA
# Define the dimensions of the raster
width, height = 100, 100
# Create a raster array with random values between 0 and 1
data = np.random.random((height, width)).astype('float32')
# Define the transform - specifies the bounding box in coordinate system units
transform = from_origin(west=-90, north=45, xsize=0.5, ysize=0.5)
# Define the coordinate reference system (CRS) - using EPSG code for WGS84
crs = 'EPSG:4326'
# Create a new raster file with one band
with rasterio.open(
os.path.join(work_folder, 'random_raster.tif'), # file name and path
'w', # w for write mode
driver='GTiff', # GeoTIFF format
height=height, # number of pixels vertically
width=width, # number of pixels horizontally
count=1, # number of bands
dtype=data.dtype, # data type of the array
crs=crs, # coordinate reference system
transform=transform # affine transformation matrix
) as dst:
dst.write(data, 1) # write data to the first band
x_start, y_start = -90, 45
x_end, y_end = -50, 10
# Create a list of linestrings
linestrings = [
LineString([(x_start+1, y_start-1), (x_end-1, y_end+1)]),
LineString([(x_start+1, y_start-5), (x_end-1, y_end+5)]),
LineString([(x_start+2, y_start-7), (x_end-5, y_end+10)]),
LineString([(x_start+3, y_start-10), (x_end-10, y_end+20)]),
LineString([(x_start+4, y_start-20), (x_end-30, y_end+30)])
]
# Create a GeoDataFrame from the linestrings
gdf = gpd.GeoDataFrame({'geometry': linestrings}, crs="EPSG:4326")
gdf["dist1"] = [1, 1, 1, 1, 1]
gdf["dist2"] = [2, 2, 2, 2, 2]
gdf.to_file(os.path.join(work_folder,"Lines.shp"))
## PROCESSING
def myfunc(row):
line = row.geometry
dist_list = [0, row.dist1, row.dist2, line.length]
final_coords = []
with rasterio.open(raster_file) as raster_obj:
for dist in dist_list:
Pt = line.interpolate(dist)
row, col = raster_obj.index(Pt.x,Pt.y)
window = rasterio.windows.Window(col, row, 1, 1)
raster_value = raster_obj.read(1, window=window)[0][0]
final_coords.append((Pt.x, Pt.y, raster_value))
line_strings = [LineString(final_coords[i:i+2]) for i in range(len(final_coords) - 1)]
gpd_out = gpd.GeoDataFrame(line_strings, columns=["geometry"], geometry="geometry")
gpd_out["Dist"] = dist_list[:-1]
return gpd_out
gpd_in = gpd.read_file(os.path.join(work_folder,"Lines.shp"))
raster_file = os.path.join(work_folder, 'random_raster.tif')
gpd_out = gpd.pd.concat([myfunc(row) for row in gpd_in.itertuples()], ignore_index=True).set_crs(gpd_in.crs)
Подробнее здесь: https://stackoverflow.com/questions/784 ... mes-in-pyt
Параллельная обработка строк фрейма геоданных для создания нескольких фреймов геоданных в Python ⇐ Python
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение