Support vector-valued UxDataArrays in vector calculus operations
维护者通常 4 天内回复
@Sevans711 已经在做这个了。
开始于 2026年11月6日。
评估
这个 Issue 还没有评估数据。
描述
Attempting to solve #1878 by implementing vector calculus methods into UxDataset directly from their current form raises lots of questions:
- gradient() outputs a UxDataset already, with "zonal_gradient" and "meridional_gradient" data vars. So:
- (1a) What should ds.gradient() look like?
- (1b) If ds has data vars "T", "P", should the result have twice as many vars, something like "T_zonal_gradient", "T_meridional_gradient", "P_zonal_gradient", "P_meridional_gradient"?
- (1c) Or, should the output be two UxDataArrays, one with zonal gradients and the other with meridional gradients?
- curl(), divergence(), and scalardotgradient() take the zonal and meridional components as separate input arrays. So:
- (2a) What would ds.curl() mean?
- (2b) Or, should the API look like u_ds.curl(v_ds) instead, where u_ds is a dataset of zonal components and v_ds is a dataset of meridional components?
- (2c) Should uxarray allow u_ds.curl(v) where v is a single UxDataArray, and/or u.curl(v_ds)?
- (2d) How can one unambiguously provide the scalar field
qinto a call to ds.scalardotgradient()?
Instead of answering these questions directly, this issue focuses on proposing a new option for existing vector calculus methods that would remove the need to ever answer most/all of these design questions in the first place.
Proposal
My proposed solution is to add an option throughout the UxDataArray vector calculus methods which allows utilizing arrays with zonal and meridional components are stacked together into a single array with a vector dimension, instead of forcing them to be treated separately. For example, one could provide a wind array stacked along a "component" dimension, instead of two separate arrays for wind_zonal and wind_meridional. This option could be implemented in a way which is fully backwards compatible; here is a rough sketch:
def gradient(self, scale_by_radius=True, *, vector_dim=None):
"""returns a UxDataset with "zonal_gradient" and "meridional_gradient" data vars.
If vector_dim is provided, instead return a UxDataArray,
with zonal and meridional results stacked along this dim."""
# ...
def curl(self, other=None, scale_by_radius=True, *, vector_dim="component"):
"""returns a UxDataArray telling curl(self, other).
If other is None, self must contain vector_dim with "zonal" and "meridional" coords;
zonal and meridional components will be inferred as self.sel({vector_dim: "zonal"})
and self.sel({vector_dim: "meridional"})."""
# ...
def divergence(self, other=None, scale_by_radius=True, *, vector_dim="component"):
# similar to curl()
For scalardotgradient, I would maybe not add an option like this at all, due to a bit of ambiguity / reduced benefits due to the additional scalar field input. Also, when utilizing the "stack along vector dimension" option, the arithmetic of the scalardotgradient functionality becomes an extremely simple one-liner anyway: wind.sel(component="zonal").scalardotgradient(wind.sel(component="meridional"), q) can be expressed simply as (wind * q.gradient()).sum("component").
This option would make it easy to add a UxDataset implementation in #1873 because it changes the inputs/outputs to always be a single UxDataArray, like "UxDataArray --> UxDataArray" for gradient, curl, and divergence. (As opposed to their current inputs/outputs, which look like "UxDataArray --> UxDataset" for gradient, and "(UxDataArray, UxDataArray) --> UxDataArray" for curl and divergence.)
Additional Benefits
I noticed these points of friction a while ago but hadn't created an issue report because they aren't necessarily convincing enough on their own to fully warrant maintaining a new feature / alternative syntax. But, they would come along with this new feature for free:
- Users who use vector_dim no longer need to remember the special names "zonal_gradient" and "meridional_gradient" for the data vars output by gradient()
- Users who use vector_dim no longer have any chance to accidentally swap the argument order for something like A.curl(B).
- It becomes easier to chain operators together, such as in the scalardotgradient example above. Another example could be a drop-in replacement for the Laplacian like
T.gradient(vector_dim="component").divergence(). The equivalent syntax users currently have available to them looks like:g = T.gradient(); g["zonal_gradient"].divergence(g["meridional_gradient"]).
Misc. notes
There is some xarray precedent for having a dimension be "the vector dimension" such as in xr.cross(a, b, dim=...) which computes cross products along a named component dimension which the inputs must be stacked along (e.g. a is really a_x, a_y, a_z stacked along dim).
Maybe some day the default for gradient() might shift to be to output a single UxDataArray along the vector_dim, and the default vector_dim could be component, but that would require a deprecation cycle, might not be desired, and is out of scope for this issue.
AI disclosure: The proposal here looks very close to my initial thoughts on the topic, but I did work through ideas extensively with Claude (Opus 5.5), including various possible alternatives and figuring out which pieces to highlight here, with the goal of narrowing in on a proposal that is most likely to be appealing to the uxarray dev team, based on my understanding of team preferences. I wrote up this issue report myself; it's long because there is a lot of content, not due to extra verbose AI rambling.
- 主要语言
- Python
- 星标
- 232
- 派生
- 59
- 平均合并
- 5 天 21 小时
- 30 天内合并 PR
- 19
环境准备
- 没有 Dockerfile 或 Docker Compose 文件
- 有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
UXARRAY/uxarray 的其他 Issue
-
ux.open_dataset currently supports structured data可能已有人在做 @Sevans711 于 9 天前认领。 未关闭bug
难度 2/5 1-3 小时 新手友好度 72/100
UXARRAY/uxarray#1854 · 2 条评论 · 已指派 1 人 ·
维护者通常 4 天内回复
-
developer experience
难度 1/5 1 小时以内 新手友好度 90/100
维护者通常 4 天内回复
-
zonal_mean() and weighted_mean() should return the same type of object可能重新可做 @Sevans711 于 47 天前认领,目前没有进行中的 PR。 未关闭bug
难度 2/5 1-3 小时 新手友好度 72/100
UXARRAY/uxarray#1733 · 已指派 1 人 ·
维护者通常 4 天内回复
-
documentation
难度 2/5 1-3 小时 新手友好度 70/100
维护者通常 4 天内回复
-
Implement UxDataArray vector calculus methods on UxDataset可能已有人在做 @Sevans711 今天认领。 未关闭new feature
UXARRAY/uxarray#1878 · 已指派 1 人 ·
维护者通常 4 天内回复
相似的 Issue
-
难度 2/5 1-3 小时 新手友好度 82/100
aws-samples/sample-per-model-bedrock#795 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 74/100
维护者通常 1 天内回复
-
Pretalx reports older version to be the latest release than what is actually installed and available未关闭
难度 2/5 1-3 小时 新手友好度 68/100
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 70/100
维护者通常 1 天内回复
-
bug
难度 2/5 1-3 小时 新手友好度 75/100
micropython/micropython#19906 ·
维护者通常 1 天内回复