如何从几个Xarray数据阵列中制作动态/递归函数

发布于 2025-02-07 02:11:01 字数 3467 浏览 3 评论 0原文

问题

我想从另一个两个时间序列计算中计算数据阵列的 。所需的输出是一个投影,其中第一年是在另一个数据阵列中定义的,然后在给定年后,投影取决于两个方面:另一个变量和往年计算(或给定)的值。

Excel的示例是以更少的维度获取想法

,它在Excel中会很简单。在此示例中,计算是上一年的值,加上“其他变量”

“在此处输入图像说明”

示例数据

import xarray as xr
given_projection = xr.DataArray.from_dict({'dims': ('energia_vehiculo', 'escenarios', 'ano'), 'attrs': {}, 'data': [[[0, 52.24501200000003, 54.334812480000025, 56.48730697440003], [0, 62.24937600000011, 64.73935104000013, 67.30402533120008]], [[299.695, 302.81542434, 305.9407876536, 309.070039330008], [299.695, 302.26518432, 304.8182980128, 307.35263017958397]]], 'coords': {'escenarios': {'dims': ('escenarios',), 'attrs': {}, 'data': ['Tendencial', 'Aspiracional']}, 'ano': {'dims': ('ano',), 'attrs': {}, 'data': [2020, 2021, 2022, 2023]}, 'tipo_vehiculo': {'dims': (), 'attrs': {}, 'data': 'Buses'}, 'energia_vehiculo': {'dims': ('energia_vehiculo',), 'attrs': {}, 'data': ['BEV', 'Convencional']}}, 'name': 'Nuevos 2020-2028'})
da_forcalculation = xr.DataArray.from_dict({'dims': ('escenarios', 'energia_vehiculo', 'ano'), 'attrs': {}, 'data': [[[5449.0, 5505.734988, 5562.559775520001, 5619.4552605456, 5676.401541062016, 5733.37789069487, 5790.362733696614, 5847.33361926215, 5904.267195156828], [0.0, 52.24501200000003, 106.57982448000006, 163.06713145440008, 221.77129877798416, 282.75840594192977, 346.09628887292206, 411.8545837587772, 480.1047719245175]], [[5449.0, 5495.730624, 5542.15087296, 5588.229639628799, 5633.934696615167, 5679.232664025139, 5724.088976252862, 5768.467847904085, 5812.332238830856], [0.0, 62.24937600000011, 126.98872704000024, 194.29275237120032, 264.23814322483247, 336.90363261166146, 412.3700463166736, 490.7203551168416, 572.0397282504896]]], 'coords': {'tipo_vehiculo': {'dims': (), 'attrs': {}, 'data': 'Buses'}, 'ano': {'dims': ('ano',), 'attrs': {}, 'data': [2020, 2021, 2022, 2023, 2024, 2025, 2026, 2027, 2028]}, 'energia_vehiculo': {'dims': ('energia_vehiculo',), 'attrs': {}, 'data': ['Convencional', 'BEV']}, 'escenarios': {'dims': ('escenarios',), 'attrs': {}, 'data': ['Tendencial', 'Aspiracional']}}, 'name': 'Parque'})

首先尝试

ds=da_forcalculation*0

for t in range(2020,2028):
    if t<=2023:
        ds=ds.drop_sel(ano=t)
        ds=xr.concat([ds,given_projection.sel(ano=t)], "ano")
    else:
        ds=ds.sortby('ano')
        v=da_forcalculation.sel(ano=t)+ds.shift(ano=3).sel(ano=t)
        ds=ds.drop_sel(ano=t)
        ds=xr.concat([ds,v], "ano")
ds

这种尝试的作品,但我希望有一种更好或更清洁的方法可以做到这一点。

(如果某人熟悉Lumina Analytica,那就像动态功能。)

更新

第二次尝试(不起作用),

根据@michael Delgado的评论,

da_final=da_forcalculation*0

for t in range(2020,2028):
    if t<=2023:
        da_final.loc[{"ano":t}]=given_projection.loc[{"ano":t}]
    else:
        da_final=da_final.sortby('ano')
        da_final.loc[{"ano":t}] = da_forcalculation.loc[{"ano":t}]+da_final.shift(ano=3).loc[{"ano":t}]

我构建了一种更好的方法,可以使用loc sigsment。它获取错误indexError:dimension坐标'Energia_vehiculo'之间的索引和索引对象之间的冲突,所以我认为我需要某种类型的redindex,也许 xr.dataarray.reindex ,但我不知道该怎么做。

The Problem

I want to calculate a DataArray from another two time-series calculation. The desired output is a projection where the first years are defined in another dataarray and then after a given year, the projection depends on two things: another variable and the value calculated (or given) in previous years.

Excel's example to get the idea

With fewer dimensions, it would be straightforward in Excel. In this example the calculation is the value of the previous year plus the "other variable"

enter image description here

Example data

import xarray as xr
given_projection = xr.DataArray.from_dict({'dims': ('energia_vehiculo', 'escenarios', 'ano'), 'attrs': {}, 'data': [[[0, 52.24501200000003, 54.334812480000025, 56.48730697440003], [0, 62.24937600000011, 64.73935104000013, 67.30402533120008]], [[299.695, 302.81542434, 305.9407876536, 309.070039330008], [299.695, 302.26518432, 304.8182980128, 307.35263017958397]]], 'coords': {'escenarios': {'dims': ('escenarios',), 'attrs': {}, 'data': ['Tendencial', 'Aspiracional']}, 'ano': {'dims': ('ano',), 'attrs': {}, 'data': [2020, 2021, 2022, 2023]}, 'tipo_vehiculo': {'dims': (), 'attrs': {}, 'data': 'Buses'}, 'energia_vehiculo': {'dims': ('energia_vehiculo',), 'attrs': {}, 'data': ['BEV', 'Convencional']}}, 'name': 'Nuevos 2020-2028'})
da_forcalculation = xr.DataArray.from_dict({'dims': ('escenarios', 'energia_vehiculo', 'ano'), 'attrs': {}, 'data': [[[5449.0, 5505.734988, 5562.559775520001, 5619.4552605456, 5676.401541062016, 5733.37789069487, 5790.362733696614, 5847.33361926215, 5904.267195156828], [0.0, 52.24501200000003, 106.57982448000006, 163.06713145440008, 221.77129877798416, 282.75840594192977, 346.09628887292206, 411.8545837587772, 480.1047719245175]], [[5449.0, 5495.730624, 5542.15087296, 5588.229639628799, 5633.934696615167, 5679.232664025139, 5724.088976252862, 5768.467847904085, 5812.332238830856], [0.0, 62.24937600000011, 126.98872704000024, 194.29275237120032, 264.23814322483247, 336.90363261166146, 412.3700463166736, 490.7203551168416, 572.0397282504896]]], 'coords': {'tipo_vehiculo': {'dims': (), 'attrs': {}, 'data': 'Buses'}, 'ano': {'dims': ('ano',), 'attrs': {}, 'data': [2020, 2021, 2022, 2023, 2024, 2025, 2026, 2027, 2028]}, 'energia_vehiculo': {'dims': ('energia_vehiculo',), 'attrs': {}, 'data': ['Convencional', 'BEV']}, 'escenarios': {'dims': ('escenarios',), 'attrs': {}, 'data': ['Tendencial', 'Aspiracional']}}, 'name': 'Parque'})

First attempt

ds=da_forcalculation*0

for t in range(2020,2028):
    if t<=2023:
        ds=ds.drop_sel(ano=t)
        ds=xr.concat([ds,given_projection.sel(ano=t)], "ano")
    else:
        ds=ds.sortby('ano')
        v=da_forcalculation.sel(ano=t)+ds.shift(ano=3).sel(ano=t)
        ds=ds.drop_sel(ano=t)
        ds=xr.concat([ds,v], "ano")
ds

This attempt kind of works, but I hope there is a better or cleaner way to do it.

(If someone is familiar with Lumina Analytica it would be like Dynamic function.)

UPDATE

Second attempt (not working)

Based on the comments of @Michael Delgado I structured a better way to do it with loc assignment.

da_final=da_forcalculation*0

for t in range(2020,2028):
    if t<=2023:
        da_final.loc[{"ano":t}]=given_projection.loc[{"ano":t}]
    else:
        da_final=da_final.sortby('ano')
        da_final.loc[{"ano":t}] = da_forcalculation.loc[{"ano":t}]+da_final.shift(ano=3).loc[{"ano":t}]

It gets the error IndexError: dimension coordinate 'energia_vehiculo' conflicts between indexed and indexing objects so I supposed I need some kind of reindexing with maybe xr.DataArray.reindex but I couldn't figure out how to do it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文