【发布时间】:2021-10-22 08:29:00
【问题描述】:
我需要使用 python 的 pvlib 包 (https://pvlib-python.readthedocs.io/en/stable/) 计算阵列平面 (POA) 辐照度。为此,我想使用 WRF 模型(GHI、DNI、DHI)的输出数据。输出数据为 netCDF 格式,我使用 netCDF4 包打开,然后使用 wrf-python 包提取必要的变量。
这样我得到了一个 xarray.Dataset ,其中包含我将使用的变量。然后我使用 xarray.Dataset.to_dataframe() 方法将其转换为 pandas 数据帧,然后使用 dataframe.values 将数据帧转换为 numpy 数组。然后我做一个循环,在每次迭代中,我使用函数 irradiance.get_total_irradiance (https://pvlib-python.readthedocs.io/en/stable/auto_examples/plot_ghi_transposition.html) 作为网格点计算 POA。
到目前为止,我就是这样做的,但是我在 WRF 域中有超过 160000 个网格点,数据是每小时一次,跨越 365 天。这提供了非常大量的数据。我相信如果 pvlib 可以直接与 xarray.dataset 一起使用它可能会更快。但是,我只能这样做,将数据转换为 numpy.array 并循环遍历行。谁能告诉我如何优化这个计算?因为我开发的代码非常耗时。
如果有人可以帮助我,我将不胜感激。也许是对代码的改进,或者是从 WRF 数据计算 POA 的另一种方法......
我正在提供我目前构建的代码:
from pvlib import location
from pvlib import irradiance
import os
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import xarray as xr
import netCDF4
import wrf
获取 WRF 数据
variaveis = ['T2',
'U10',
'V10',
'SWDDNI',
'SWDDIF',
'SWDOWN']
netcdf_data = netCDF4.Dataset('wrfout_d02_2003-11-01_00_00_00')
first = True
for v in variaveis:
var = wrf.getvar(netcdf_data, v, timeidx=wrf.ALL_TIMES)
if first:
met_data = var
first = False
else:
met_data = xr.merge([met_data, var])
met_data = xr.Dataset.reset_coords(met_data, ['XTIME'], drop=True)
met_data['T2'] = met_data['T2'] - 273.15
WS10 = (met_data['U10']**2 + met_data['V10']**2)**0.5
met_data['WS10'] = WS10
df = met_data[['SWDDIF',
'SWDDNI',
'SWDOWN',
'T2',
'WS10']].to_dataframe().reset_index().drop(columns=['south_north',
'west_east'])
df.rename(columns={'SWDOWN': 'ghi',
'SWDDNI':'dni',
'SWDDIF':'dhi',
'T2':'temp_air',
'WS10':'wind_speed',
'XLAT': 'lat',
'XLONG': 'lon',
'Time': 'time'}, inplace=True)
df.set_index(['time'], inplace=True)
df = df[df.ghi>0]
df.index = df.index.tz_localize('America/Recife')
获取 POA 辐照度的函数
def get_POA_irradiance(lon, lat, date, dni, dhi, ghi, tilt=10, surface_azimuth=0):
site_location = location.Location(lat, lon, tz='America/Recife')
# Get solar azimuth and zenith to pass to the transposition function
solar_position = site_location.get_solarposition(times=date)
# Use the get_total_irradiance function to transpose the GHI to POA
POA_irradiance = irradiance.get_total_irradiance(
surface_tilt = tilt,
surface_azimuth = surface_azimuth,
dni = dni,
ghi = ghi,
dhi = dhi,
solar_zenith = solar_position['apparent_zenith'],
solar_azimuth = solar_position['azimuth'])
# Return DataFrame with only GHI and POA
return pd.DataFrame({'lon': lon,
'lat': lat,
'GHI': ghi,
'POA': POA_irradiance['poa_global']}, index=[date])
在数组的每一行(时间)循环
array = df.reset_index().values
list_poa = []
def loop_POA():
for i in tqdm(range(len(array) - 1)):
POA = get_POA_irradiance(lon=array[i,6],
lat=array[i,7],
dni=array[i,2],
dhi=array[i,1],
ghi=array[i,3],
date=str(array[i,0]))
list_poa.append(POA)
return list_poa
poa_final = pd.concat(lista)
【问题讨论】:
-
旁白,你试过用
xr.open_dataset读取数据吗?只是好奇你为什么要直接使用 netCDF 包 -
嗯,是的,其他人可能有更好的特定领域新闻,但基于对 pvlib 包的一些非常快速的挖掘,它不是为了处理具有额外维度或任何东西的 numpy 数组而编写的。如果数组的每个组件都需要由纯 python 函数处理,这会很慢。据我所知,您的选择是重写您需要的函数,或者只是使用 dask 或其他并行处理库来加快总运行时间。
-
这是一个 numfocus 项目,但他们可能会遇到同样的问题。您可能会更幸运地发布问题或使用他们的邮件列表。
-
WRF 输出有太阳位置吗?如果是这样,请使用它并为自己节省计算时间。大多数低级转置函数都可以接受更高维度的输入,因此请使用它们而不是像 get_total_irradiance 这样的包装器。
-
亲爱的,非常感谢您的回答。 @Michael Delgado,我在 wrf-python 文档之后直接使用 netCDF 包。上次我检查 getvar 函数不适用于 xarray.Dataset。感谢其他建议。
标签: python numpy python-xarray pvlib