使用PVLIB转换辐照度时生成NaN值问题排查
解决PVLIB转换水平面辐照度到垂直面时生成NaN的问题
看起来你在把PVGIS的小时级水平面数据转成西向垂直面辐照度时遇到了NaN的问题,我帮你梳理几个最可能的原因和解决办法:
1. 未定义location对象导致太阳位置计算错误
你代码里用了location.latitude和location.longitude,但前面只定义了单独的latitude = 45.466和longitude = 9.183,没有创建对应的location对象!这会直接导致太阳位置计算失败,得到的solpos数据大概率全是NaN,后续辐照度转换自然也会输出NaN。
修正方法:
要么直接用你已经定义好的经纬度参数,要么规范创建pvlib的Location对象:
# 方法1:直接使用已定义的经纬度 solpos = pvlib.solarposition.get_solarposition( times, latitude, longitude ) # 方法2:创建Location对象(更符合pvlib使用规范) location = pvlib.location.Location(latitude, longitude, timezone=timezone, altitude=altitude) solpos = location.get_solarposition(times)
2. 时间序列未对齐(高频触发原因)
你手动生成了times时间序列,但没有确保它和CSV读取的irrad_horz_ERA5['Date']完全匹配:
- 检查CSV读取的
Date列是否设置了时区(你给times指定了Europe/Rome,但原始CSV的日期是 naive 状态) - 确认两个时间序列的长度、时间戳完全对应(比如你生成了52584个小时,要确保CSV的行数也是52584行)
优化方案:
直接用CSV中的Date列作为太阳位置计算的时间输入,避免手动生成的偏差:
# 给读取的日期列设置时区 irrad_horz_ERA5['Date'] = irrad_horz_ERA5['Date'].dt.tz_localize('Europe/Rome') # 用该时间列计算太阳位置 solpos = pvlib.solarposition.get_solarposition( irrad_horz_ERA5['Date'], latitude, longitude )
3. 原始CSV数据存在缺失值
检查你的ghi、Bi、Di列本身是否就有NaN值:
print(irrad_horz_ERA5[['ghi', 'Bi', 'Di']].isna().sum())
如果原始数据存在缺失,转换后的结果自然会出现NaN。可以用线性插值填充:
irrad_horz_ERA5[['ghi', 'Bi', 'Di']] = irrad_horz_ERA5[['ghi', 'Bi', 'Di']].interpolate(method='linear')
4. 太阳在地平线以下的正常情况
当太阳天顶角(apparent_zenith)大于90度时,说明太阳未升起或已落下,此时get_total_irradiance会返回NaN,这是合理现象。你可以把这些NaN替换为0:
westERA5 = westERA5.fillna(0)
修正后的完整代码片段
import pandas as pd import pvlib # 创建lambda函数解析csv中的日期 mydateparser = lambda x: pd.datetime.strptime(x, "%Y%m%d:%H%M") irrad_horz_ERA5 = pd.read_csv( (r'C:\Users\dpaul\OneDrive\1st part\Downloaded csv\PVGISERA5\Horizontal' r'\Timeseries_45.467_9.191_E5__0deg_0deg_2010_2016.csv'), parse_dates=['Date'], date_parser=mydateparser) # 为日期列设置时区 irrad_horz_ERA5['Date'] = irrad_horz_ERA5['Date'].dt.tz_localize('Europe/Rome') latitude = 45.466 longitude = 9.183 altitude = 120 timezone = 'Europe/Rome' ground_albedo = 0.2 # 基于CSV的时间列计算太阳位置 solpos = pvlib.solarposition.get_solarposition( irrad_horz_ERA5['Date'], latitude, longitude ) # 确保数值类型正确 columns = ['apparent_zenith', 'azimuth'] solpos[columns] = solpos[columns].apply(pd.to_numeric, axis=1) cols = ['ghi', 'Bi', 'Di'] irrad_horz_ERA5[cols] = irrad_horz_ERA5[cols].apply(pd.to_numeric, axis=1) # 填充原始数据缺失值 irrad_horz_ERA5[cols] = irrad_horz_ERA5[cols].interpolate(method='linear') # 计算西向垂直面辐照度 westERA5 = pvlib.irradiance.get_total_irradiance( surface_tilt=90, surface_azimuth=270, solar_zenith=solpos.apparent_zenith, solar_azimuth=solpos.azimuth, ghi=irrad_horz_ERA5.ghi, dni=irrad_horz_ERA5.Bi, dhi=irrad_horz_ERA5.Di, albedo=ground_albedo ) # 替换太阳未升起时的NaN为0 westERA5 = westERA5.fillna(0) print(westERA5.head(20))
建议先排查location对象的问题,这是最可能导致全量NaN的原因。
内容的提问来源于stack exchange,提问作者Debayan Paul
相关产品推荐
相关产品推荐

