简体   繁体   English

如何使用 xarray 中的维度和数据来创建新的数据数组?

[英]How can I use dimensions and data in xarray to create a new array of data?

I'm running into issues with DataSets in Xarray .我在Xarray遇到了 DataSet 的问题。 I'd like to apply a function to data and coordinates already in the dataset to compute a new set of data (essentially, w = f ( x, y, z ), where x , y , and z are floats).我想对数据集中已有的数据和坐标应用一个函数来计算一组新数据(本质上, w = f ( x, y, z ),其中xyz是浮点数)。

There are a series of functions that need to be applied, and the dimensions of the resulting array need to expand when a new variable is pulled in. So f(x) should be a 1D array, g(f(x), y) should be 2D, and h(g(f(x), y), z) should be a 3D array created from the previous 2D array.有一系列的函数需要应用,当拉入一个新的变量时,结果数组的维度需要扩展。所以f(x)应该是一个一维数组,g(f(x),y)应该是 2D 的,而 h(g(f(x), y), z) 应该是从之前的 2D 数组创建的 3D 数组。 I'm able to use np.outer to force the 1D -> 2D transformation, but I'm having trouble with the 2D -> 3D conversion.我可以使用np.outer强制进行 1D -> 2D 转换,但是我在 2D -> 3D 转换方面遇到了麻烦。 Given the amount of trouble I'm having, I suspect I'm coming at the problem from the wrong direction.考虑到我遇到的麻烦,我怀疑我是从错误的方向来解决问题的。

Below is a snippet of some of the code.下面是部分代码的片段。 Can someone help me understand the correct way to approach this problem from a NumPy/Xarray standpoint (I'm really trying avoid dropping to a loop for this work…)有人可以帮助我从 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

As you can see, the radial_decay function doesn't broadcast into the z dimension.如您所见, radial_decay函数不会广播到z维度。 It seems like Xarray should support this type of operation, but I don't know how to approach the problem, or even where to start in the documentation.似乎 Xarray 应该支持这种类型的操作,但我不知道如何解决这个问题,甚至不知道从文档中的哪里开始。 I currently have two datasets to which I'd like to apply these function, so I could do it by hand, but I want to make a framework I can use on future data as well.我目前有两个数据集,我想应用这些函数,所以我可以手工完成,但我想制作一个框架,我也可以在未来的数据上使用。

After playing around a bit and using the function structure found in this answer , I was able to come up with an output of the right shape.在玩了一会儿并使用了在这个答案中找到的函数结构之后,我能够想出一个正确形状的输出。

By defining the radial_decay function as follows, I can get an output array with three dimensions.通过如下定义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

With this structure, the output of radial_decay(data.isel(x=[1, 4, 10])).radial_decay.shape is (3, 500000, 125) , rather than (1500000,125) using the function defined in the original question.使用这种结构, radial_decay(data.isel(x=[1, 4, 10])).radial_decay.shape(3, 500000, 125) ,而不是(1500000,125)使用定义在原始问题。

While this seems to work (I still need to verify that the values are correct), I'd like to know if there are any other (better?) methods to achieve this goal, particularly if there are better ways with just NumPy to do this (in case I don't have access to Xarray for some reason in the future).虽然这似乎有效(我仍然需要验证这些是否正确),但我想知道是否还有其他(更好的?)方法来实现这个目标,特别是如果只有NumPy 有更好的方法来做这个(以防我将来由于某种原因无法访问 Xarray )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM