python - 如何使用 xarray 中的维度和数据来创建新的数据数组?
问题描述
我在Xarray中遇到了 DataSets 的问题。我想对数据集中已有的数据和坐标应用一个函数来计算一组新数据(本质上,w = f ( x, y, z ),其中x、y和z是浮点数)。
有一系列函数需要应用,并且当拉入一个新变量时,结果数组的维度需要扩展。所以 f(x) 应该是一维数组,g(f(x), y)应该是 2D,h(g(f(x), y), z) 应该是从前一个 2D 数组创建的 3D 数组。我可以用来np.outer
强制 1D -> 2D 转换,但我在 2D -> 3D 转换时遇到问题。考虑到我遇到的麻烦,我怀疑我是从错误的方向来解决问题的。
下面是部分代码的片段。有人能帮我理解从 NumPy/Xarray 的角度解决这个问题的正确方法吗(我真的在努力避免陷入循环来完成这项工作……)
import numpy as np
import xarray as xr
data = xr.Dataset(
data_vars={
"abs": (("x"), np.ones((200)))
},
coords={
"x": np.linspace(1.5,1.55,200),
"y": np.arange(5e5),
"z": np.arange(125)
}
)
def intensity_decay(da):
"Return decay curve (exponential decay)."
init_power = 1e5
decay = init_power * np.exp(
-1 * np.outer(da.abs, da.y * 10 ** (-7))
)
decay[decay < 1e-3] = 0
return decay
data["depth_decay"] = (["x", "y"], intensity_decay(data))
def radial_decay(da):
"Return radial decay curve."
return np.outer(da.depth_decay, np.exp(-da.z))
radial_decay(data.isel(x=[1, 4, 10])).shape
如您所见,该radial_decay
函数不会广播到z维度。似乎 Xarray 应该支持这种类型的操作,但我不知道如何解决这个问题,甚至不知道从文档中的哪里开始。我目前有两个要应用这些功能的数据集,所以我可以手动完成,但我想创建一个框架,我也可以在未来的数据上使用。
解决方案
在玩了一会儿并使用这个答案中找到的函数结构之后,我能够想出正确形状的输出。
通过radial_decay
如下定义函数,我可以得到一个具有三个维度的输出数组。
def radial_decay(da):
"Return radial decay curve."
da["radial_decay"] = (["x", "y", "z"], da.depth_decay * np.exp(-da.z))
return da
使用这种结构,输出radial_decay(data.isel(x=[1, 4, 10])).radial_decay.shape
is (3, 500000, 125)
,而不是(1500000,125)
使用原始问题中定义的函数。
虽然这似乎可行(我仍然需要验证这些值是否正确),但我想知道是否还有其他(更好的?)方法可以实现这一目标,特别是如果只有NumPy 有更好的方法可以做这个(以防我将来由于某种原因无法访问 Xarray)。
推荐阅读
- django - 在 Django 中自定义错误消息“请填写此表格”
- countif - COUNTIFS() 用于定义为 NAME 的非连续范围
- visual-studio - 签入 TFS 时,Visual Studio 找不到路径 system.net.http 的一部分
- django - 禁止 403:Firefox 中的 CSRF 验证失败错误,而不是 chrome
- javascript - 节点动态参数和从函数传递信息到变量
- sql - 选择指定记录后的下 3 条记录时缺少数据
- liquibase - Liquibase 可以处理不带引号的 csv 数据吗
- javascript - JavaScript ES6 模块:避免污染全局命名空间
- docker - Jenkins Pipeline 和 Docker - 如何从容器归档文件
- scala - 有没有办法通过 Scala 的 breakOut 来保持排序?