我有一個字典(list_image_dict)和一個串列(structures.geometry),我想將字典中的每個值與串列中的值進行比較,對其執行快速操作并替換字典中的值。
但是list_image_dict包含 300623 個鍵/值對,遍歷所有值并將它們與 的每個元素進行比較structures.geometry是很長的。幾十分鐘。我的問題是如何提高執行速度?
我嘗試通過簡單list_image串列中的16 個內核進行多處理。串列中的每個元素都與structures.geometry 的元素并行比較,它有點快但仍然很慢(仍然是幾十分鐘)。structures.geometry僅包含 156 個元素。
def make_sort(layers, structures, threshold):
def coverage(a, b): return a.area/b.area*100
def label(
polygon): return structures.loc[structures.geometry == polygon, "label"].values[0]
frames = pd.concat([*layers], ignore_index=True)
frames.crs = "epsg:3857"
frames = frames.to_crs(epsg=4326)
main = gpd.GeoDataFrame(geometry=frames.geometry)
list_image = main.geometry.tolist()
#list_image has 300623 elements.
list_image_dict = {images.wkt: images for images in list_image}
for key, value in list_image_dict.items(): #main loop on list_image_dict
liste=[]
for item in structures.geometry: #structures has 156 elements.
if value.intersects(item):
x = value.intersection(item)
#for a certain threshold coverage (in percent) present on the image
#the polygon is added to the liste.
if coverage(x, item) >= threshold:
liste.append([x, str(label(item))])
list_image_dict[key] = liste
return list_image_dict
在評論中的人的幫助下,這種方式減少了幾分鐘,但仍然很長。
def make_sort(layers, structures, threshold):
def coverage(a, b): return a.area/b.area*100
label = structures["label"].to_list()
geom = structures["geometry"].to_list()
frames = pd.concat([*layers], ignore_index=True)
frames.crs = "epsg:3857"
frames = frames.to_crs(epsg=4326)
main = gpd.GeoDataFrame(geometry=frames.geometry)
final = []
for elem in main.geometry:
liste=[]
for item in structures.geometry:
if coverage(elem.intersection(item), item) >= threshold:
liste.append([elem.intersection(item), label[geom.index(item)]])
final.append({elem.wkt: liste})
result = dict(ChainMap(*final))
return result
uj5u.com熱心網友回復:
IIUC,現在,您有 2 個 GeoDataFrame:main(300623 個多邊形)和structures(156 個多邊形)。首先,您要找到交點,然后僅選擇覆寫范圍大于 的多邊形threshold。瓶頸是找到從structures到 的 300K 個多邊形的一個多邊形的交集main。
我認為更好的解決方案是使用Spatial Index和R-Tree。為此,您需要安裝PyGeos才能訪問main.sindex.
要快速找到哪些多邊形與另一個多邊形相交:
for idx, item in structures.iterrows():
print(item['label'])
# All polygons...
indexes = main.sindex.query(item['geometry'], predicate='intersects')
# ...greater than or equal to threshold
indexes = main.iloc[indexes, main.columns.get_loc('geometry')] \
.apply(coverage, b=item['geometry']).ge(threshold) \
.loc[lambda x: x].index
# Do stuff here
...
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/312983.html
