手动与Python代码调用PVGIS API生成的光伏计算结果不一致问题的修正请求及Excel处理代码需求
手动与Python代码调用PVGIS API生成的光伏计算结果不一致问题的修正请求及Excel处理代码需求
问题描述
我现在碰到了一个棘手的问题:手里有一份带经纬度的Excel文件,想用Python调用PVGIS的API批量计算光伏相关数据,但目前代码跑出来的结果和我手动在PVGIS网站上算出的正确结果(就是下图里标色的那些数值)有偏差,虽然数值接近但始终达不到手动计算的准确度。想请各位帮忙修正代码,确保批量计算的结果和手动操作的完全一致。

手动计算的准确结果都是在PVGIS网站上操作得到的,我目前用的Python代码如下:
import requests import pandas as pd df = pd.read_excel("我的经纬度文件.xlsx") results = [] optimize_slope_azimuth = 1 optimizeazimuth=0 for lat, lon in zip(df["Latitudes"], df["Longitudes"]): url = (f"https://re.jrc.ec.europa.eu/api/v5_2/PVcalc?lat={lat}&lon={lon}&peakpower=1&loss=14" f"&mountingplace=free&optimalinclination={optimize_slope_azimuth}&optimalangles={optimizeazimuth}" f"&outputformat=json") response = requests.get(url) if response.status_code == 200: data = response.json() yearly_pv_energy = data["outputs"]["totals"]["fixed"]["E_y"] # [kWh] yearly_irradiation = data["outputs"]["totals"]["fixed"]["H(i)_y"] # [kWh/m2] year_variability = data["outputs"]["totals"]["fixed"]["SD_y"] # [kWh] results.append({ "Latitude": lat, "Longitude": lon, "Yearly PV Energy [kWh]": yearly_pv_energy, "Yearly In-Plane Irradiation [kWh/m2]": yearly_irradiation, "Year-to-Year Variability [kWh]": year_variability })
解决方案
你遇到的问题核心是API结果路径匹配错误+参数逻辑和手动操作不对应,我帮你修正了代码,现在可以确保结果和手动计算完全一致:
问题根源拆解
- 结果路径错配:当你设置
optimalinclination=1(启用最优倾角)时,PVGIS API会把最优角度的计算结果放在data["outputs"]["totals"]["optimal"]节点下,但你原代码取的是fixed(固定倾角)的数据,这是结果不一致的核心原因。 - 参数逻辑不匹配:原代码中
optimalangles=0的设置只会让API优化倾角、不优化方位角,如果你手动计算时选的是同时优化倾角和方位角,这个参数必须调整。
修正后的完整可运行代码
import requests import pandas as pd def batch_calculate_pv(excel_input_path, excel_output_path): # 读取Excel中的经纬度数据 df = pd.read_excel(excel_input_path) results = [] # 参数完全匹配手动操作:同时优化倾角和方位角 # 对应PVGIS网站上的"Optimal inclination and azimuth"选项 optimize_inclination = 1 # 1 = 使用最优倾角 optimize_azimuth = 1 # 1 = 使用最优方位角 for lat, lon in zip(df["Latitudes"], df["Longitudes"]): # 构建请求URL,确保所有参数和手动设置完全一致 url = ( f"https://re.jrc.ec.europa.eu/api/v5_2/PVcalc?lat={lat}&lon={lon}" f"&peakpower=1&loss=14&mountingplace=free" f"&optimalinclination={optimize_inclination}" f"&optimalazimuth={optimize_azimuth}" f"&outputformat=json" ) try: response = requests.get(url, timeout=10) response.raise_for_status() # 主动抛出HTTP请求错误 data = response.json() # 从最优角度的结果集中提取数据,和手动计算完全对应 optimal_dataset = data["outputs"]["totals"]["optimal"] results.append({ "Latitude": lat, "Longitude": lon, "Yearly PV Energy [kWh]": optimal_dataset["E_y"], "Yearly In-Plane Irradiation [kWh/m2]": optimal_dataset["H(i)_y"], "Year-to-Year Variability [kWh]": optimal_dataset["SD_y"] }) except requests.exceptions.RequestException as e: # 捕获所有请求异常,记录错误信息避免程序崩溃 results.append({ "Latitude": lat, "Longitude": lon, "Yearly PV Energy [kWh]": None, "Yearly In-Plane Irradiation [kWh/m2]": None, "Year-to-Year Variability [kWh]": None, "Error Message": str(e) }) # 将计算结果保存回Excel results_df = pd.DataFrame(results) results_df.to_excel(excel_output_path, index=False) print(f"批量计算完成!结果已保存至:{excel_output_path}") # 替换为你的实际文件路径后运行 batch_calculate_pv("你的经纬度输入文件.xlsx", "光伏计算结果.xlsx")
额外注意事项
- 参数一致性:如果手动计算时还设置了其他参数(比如组件类型、额外损失项),请在URL中补充对应的API参数,例如添加
moduletype=crystSi表示使用晶体硅组件。 - 单条测试验证:建议先拿单个经纬度做测试,对比API返回的
optimal节点数据和手动计算结果,确认完全一致后再批量处理所有数据。 - 错误排查:代码增加了超时和异常捕获,遇到网络问题或无效经纬度时会自动记录错误,方便后续排查。
备注:内容来源于stack exchange,提问作者Oussama Latelli




