外观
城市动态权重矩阵
按实际城市子样本、经纬度、邻接关系和样本期人均 GDP 生成 W01–W08。
核心代码
py
def build_city_weight_matrices(
*,
adjacency: np.ndarray,
coordinates: np.ndarray,
per_capita_gdp_yuan: np.ndarray,
) -> tuple[dict[str, np.ndarray], dict[str, Any]]:
"""按平台 W01–W08 固定公式一次性构造城市矩阵。"""
adjacency = np.asarray(adjacency, dtype=np.float64)
coordinates = np.asarray(coordinates, dtype=np.float64)
values = np.asarray(per_capita_gdp_yuan, dtype=np.float64).reshape(-1)
size = len(values)
if adjacency.shape != (size, size) or coordinates.shape != (size, 2):
raise ValueError(_('城市邻接、经纬度和GDP数组维度不一致'))
if not np.isfinite(adjacency).all() or not np.allclose(np.diag(adjacency), 0.0):
raise ValueError(_('城市邻接矩阵无效'))
adjacency_binary = (adjacency != 0).astype(np.float64)
distance_km = pairwise_haversine_km(coordinates)
geographic_inverse = 1.0 / distance_km
np.fill_diagonal(geographic_inverse, 0.0)
economic_inverse, economic_metadata = economic_distance_inverse(values)
destination_economic = np.tile(values, (size, 1))
np.fill_diagonal(destination_economic, 0.0)
asymmetric_economic = row_standardize(destination_economic)
matrices = {
'W01': adjacency_binary,
'W02': row_standardize(economic_inverse),
'W03': row_standardize(geographic_inverse),
'W04': row_standardize(geographic_inverse ** 2),
'W05': economic_inverse * geographic_inverse,
'W06': 0.5 * economic_inverse + 0.5 * geographic_inverse,
'W07': asymmetric_economic,
'W08': asymmetric_economic * geographic_inverse,
}
for key, matrix in matrices.items():
if matrix.shape != (size, size) or not np.isfinite(matrix).all():
raise ValueError(
_('%(key)s 生成结果包含无效数值') % {'key': key}
)
np.fill_diagonal(matrix, 0.0)
metadata = {
**economic_metadata,
'distance_method': 'haversine',
'earth_radius_km': EARTH_RADIUS_KM,
'distance_min_km': float(np.min(distance_km[np.isfinite(distance_km)])),
'distance_max_km': float(np.max(distance_km[np.isfinite(distance_km)])),
'formulas': dict(CITY_MATRIX_FORMULAS),
}
return matrices, metadata