gpt4 book ai didi

python - for 循环中的嵌套字典向所有嵌套键添加相同的值

转载 作者:行者123 更新时间:2023-12-01 07:12:04 25 4
gpt4 key购买 nike

我有带有多边形的地址数据和形状文件,并尝试确定每个地址与每个多边形的最近距离(以英里为单位),然后创建一个包含所有信息的嵌套字典,格式如下:

nested_dict = {poly_1: {address1: distance, address2 : distance}, 
poly2: {address1: distance, address2: distance}, etc}

我正在使用的完整的、适用的代码是:

import pandas as pd
from shapely.geometry import mapping, Polygon, LinearRing, Point
import geopandas as gpd
from math import radians, cos, sin, asin, sqrt

address_dict = {k: [] for k in addresses_geo.input_string}
sludge_dtc = {k: [] for k in sf_geo.unique_name}

def haversine(lon1, lat1, lon2, lat2):
"""
Calculate the great circle distance between two points
on the earth (specified in decimal degrees)
"""
# convert decimal degrees to radians
lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2])

# haversine formula
dlon = lon2 - lon1
dlat = lat2 - lat1
a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
c = 2 * asin(sqrt(a))
r = 3956 # Radius of earth in miles. Use 6371 for kilometers
return c * r

# Here's the key loop that isn't working correctly
for unique_name, i in zip(sf_geo.unique_name, sf_geo.index):
for address, pt in zip(addresses_geo.input_string, addresses_geo.index):
pol_ext = LinearRing(sf_geo.iloc[i].geometry.exterior.coords)
d = pol_ext.project(addresses_geo.iloc[pt].geometry)
p = pol_ext.interpolate(d)
closest_point_coords = list(p.coords)[0]
# print(closest_point_coords)
dist = haversine(addresses_geo.iloc[pt].geometry.x,
addresses_geo.iloc[pt].geometry.y,
closest_point_coords[0], closest_point_coords[1])
address_dict[address] = dist
sludge_dtc[unique_name] = address_dict
# Test results on a single address
addresses_with_sludge_distance = pd.DataFrame(sludge_dtc)
print(addresses_with_sludge_distance.iloc[[1]].T)

如果我打破这段代码并尝试计算单个多边形的距离,它似乎工作得很好。但是,当我创建数据帧并检查地址时,它列出了每个多边形的相同距离。

因此,内部字典键“123 Main Street”对于外部字典中的每个多边形键将具有 5.25 英里,而“456 South Street”对于外部字典中的每个多边形键将具有 6.13 英里。 (编造例子。)

我意识到我在设置 for 循环的方式中一定做了一些愚蠢的事情,但我无法弄清楚。我颠倒了 for 语句的顺序,加上缩进——结果都是一样的。

为了明确起见,我想要发生的是:

  • 取一个多边形,然后
  • 对于地址数据中的每个地址,找到距该多边形的距离,并将其添加到以地址为键、距离为值的 address_dict 字典中
  • 计算完所有地址后,将整个地址字典添加为sludge_dtc中多边形键的值
  • 移至下一个多边形并继续

我缺少什么想法吗?

最佳答案

问题很简单,您始终使用相同的 address_dict 实例。您只需在每个按键循环内重新创建它即可。

import pandas as pd
from shapely.geometry import mapping, Polygon, LinearRing, Point
import geopandas as gpd
from math import radians, cos, sin, asin, sqrt

def haversine(lon1, lat1, lon2, lat2):
"""
Calculate the great circle distance between two points
on the earth (specified in decimal degrees)
"""
# convert decimal degrees to radians
lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2])

# haversine formula
dlon = lon2 - lon1
dlat = lat2 - lat1
a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
c = 2 * asin(sqrt(a))
r = 3956 # Radius of earth in miles. Use 6371 for kilometers
return c * r

sludge_dtc = {k: [] for k in sf_geo.unique_name}

# Here's the key loop that isn't working correctly
for unique_name, i in zip(sf_geo.unique_name, sf_geo.index):

address_dict = {k: [] for k in addresses_geo.input_string}

for address, pt in zip(addresses_geo.input_string, addresses_geo.index):
pol_ext = LinearRing(sf_geo.iloc[i].geometry.exterior.coords)
d = pol_ext.project(addresses_geo.iloc[pt].geometry)
p = pol_ext.interpolate(d)
closest_point_coords = list(p.coords)[0]
# print(closest_point_coords)
dist = haversine(addresses_geo.iloc[pt].geometry.x,
addresses_geo.iloc[pt].geometry.y,
closest_point_coords[0], closest_point_coords[1])
address_dict[address] = dist
sludge_dtc[unique_name] = address_dict
# Test results on a single address
addresses_with_sludge_distance = pd.DataFrame(sludge_dtc)
print(addresses_with_sludge_distance.iloc[[1]].T)

另一个考虑因素:

您正在创建空字典,其中空列表作为值,但在您直接设置值之后(空列表将被替换)。如果您需要收集值列表,您应该附加值到现有列表,例如:

address_dict[address].append(dist)

sludge_dtc[unique_name].append(address_dict)

关于python - for 循环中的嵌套字典向所有嵌套键添加相同的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58157326/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com