【问题标题】:Selecting the value at a given date for each lat/lon point in xarray为 xarray 中的每个纬度/经度点选择给定日期的值
【发布时间】:2021-10-17 02:46:52
【问题描述】:

我有一个 xr.DataArray 对象,它对于网格上的每个 lat-lon 点都有 2015 年的一天(作为 cftime.DateTimeNoLeap 对象)。

date_matrix2015
    <xarray.DataArray (lat: 160, lon: 320)>
array([[cftime.DatetimeNoLeap(2015, 12, 11, 12, 0, 0, 0),
        cftime.DatetimeNoLeap(2015, 12, 11, 12, 0, 0, 0),
        cftime.DatetimeNoLeap(2015, 12, 11, 12, 0, 0, 0), ...,
        cftime.DatetimeNoLeap(2015, 12, 11, 12, 0, 0, 0),
        cftime.DatetimeNoLeap(2015, 12, 11, 12, 0, 0, 0),
        cftime.DatetimeNoLeap(2015, 12, 11, 12, 0, 0, 0)],
       [cftime.DatetimeNoLeap(2015, 12, 11, 12, 0, 0, 0),
        cftime.DatetimeNoLeap(2015, 12, 11, 12, 0, 0, 0),
        cftime.DatetimeNoLeap(2015, 12, 11, 12, 0, 0, 0), ...,
        cftime.DatetimeNoLeap(2015, 12, 11, 12, 0, 0, 0),
        cftime.DatetimeNoLeap(2015, 12, 11, 12, 0, 0, 0),
        cftime.DatetimeNoLeap(2015, 12, 11, 12, 0, 0, 0)],
       [cftime.DatetimeNoLeap(2015, 12, 11, 12, 0, 0, 0),
        cftime.DatetimeNoLeap(2015, 12, 11, 12, 0, 0, 0),
        cftime.DatetimeNoLeap(2015, 12, 11, 12, 0, 0, 0), ...,
        cftime.DatetimeNoLeap(2015, 12, 11, 12, 0, 0, 0),
        cftime.DatetimeNoLeap(2015, 12, 11, 12, 0, 0, 0),
        cftime.DatetimeNoLeap(2015, 12, 11, 12, 0, 0, 0)],
       ...,
       [cftime.DatetimeNoLeap(2015, 3, 14, 12, 0, 0, 0),
        cftime.DatetimeNoLeap(2015, 3, 14, 12, 0, 0, 0),
        cftime.DatetimeNoLeap(2015, 3, 14, 12, 0, 0, 0), ...,
        cftime.DatetimeNoLeap(2015, 9, 16, 12, 0, 0, 0),
        cftime.DatetimeNoLeap(2015, 9, 16, 12, 0, 0, 0),
        cftime.DatetimeNoLeap(2015, 9, 16, 12, 0, 0, 0)],
       [cftime.DatetimeNoLeap(2015, 9, 15, 12, 0, 0, 0),
        cftime.DatetimeNoLeap(2015, 9, 15, 12, 0, 0, 0),
        cftime.DatetimeNoLeap(2015, 9, 15, 12, 0, 0, 0), ...,
        cftime.DatetimeNoLeap(2015, 9, 16, 12, 0, 0, 0),
        cftime.DatetimeNoLeap(2015, 9, 15, 12, 0, 0, 0),
        cftime.DatetimeNoLeap(2015, 9, 15, 12, 0, 0, 0)],
       [cftime.DatetimeNoLeap(2015, 9, 16, 12, 0, 0, 0),
        cftime.DatetimeNoLeap(2015, 9, 16, 12, 0, 0, 0),
        cftime.DatetimeNoLeap(2015, 9, 16, 12, 0, 0, 0), ...,
        cftime.DatetimeNoLeap(2015, 9, 16, 12, 0, 0, 0),
        cftime.DatetimeNoLeap(2015, 9, 16, 12, 0, 0, 0),
        cftime.DatetimeNoLeap(2015, 9, 16, 12, 0, 0, 0)]], dtype=object)
Coordinates:
    year     int64 2015
  * lat      (lat) float64 -89.14 -88.03 -86.91 -85.79 ... 86.91 88.03 89.14
  * lon      (lon) float64 0.0 1.125 2.25 3.375 4.5 ... 355.5 356.6 357.8 358.9

我在同一个 lat-lon 网格上有另一个 xr.DataArray 用于垂直速度 (omega),它有 2015 年每天的数据。在每个 lat-lon 点我想选择相应的速度值date_matrix2015 中给出的日期。理想情况下,我想做这样的事情: omega.sel(time=date_matrix2015)

我曾尝试通过迭代手动构造新的数据数组,但运气不佳。

有人有什么想法吗?提前谢谢!

------------编辑---------------

这是该问题的最小可重现示例。为了澄清我在寻找什么:我有两个 DataArray,一个用于每日降水值,一个用于每日欧米茄值。我想为每个纬度/经度点确定最大降水量的那一天(我认为我已经正确完成了这部分)。从那里我想在每个纬度/经度点选择最大降水日发生的欧米茄值。所以最终我想得到一个欧米茄值的 DataArray,它有两个维度,纬度和经度,其中每个纬​​度/经度点的值是该位置最大降雨日的欧米茄值。

import numpy as np
import xarray as xr
import pandas as pd

precip = np.abs(8*np.random.randn(10,10,10))
omega = 15*np.random.randn(10,10,10)
lat = np.arange(0,10)
lon = np.arange(0, 10)
##Note: actual data resolution is 160x360
dates = pd.date_range('01-01-2015', '01-10-2015')

precip_da = xr.DataArray(precip).rename({'dim_0':'time', 'dim_1':'lat', 'dim_2':'lon'}).assign_coords({'time':dates, 'lat':lat, 'lon':lon})
omega_da = xr.DataArray(omega).rename({'dim_0':'time', 'dim_1':'lat', 'dim_2':'lon'}).assign_coords({'time':dates, 'lat':lat, 'lon':lon})

#Find Date of maximum precip for each lat lon point and store in an array
maxDateMatrix = precip_da.idxmax(dim='time')


#For each lat lon point, select the value from omega_da on the day of maximum precip (i.e. the date given at that location in the maxDateMatrix)

【问题讨论】:

  • omega.where(omega.time==date_matrix2015, drop=True) 只会为您提供包含与 date_matrix2015 匹配的经纬度 - 这就是您要找的吗?问题是可能有任意数量的匹配(至少就 xarray 所知),因此保持了 omega 的 2D 形状。如果这不是您要查找的内容,您能否提供完整的minimal reproducible example(可能是虚拟数据,但我们并不完全知道您的数据是如何构成的),并澄清您对您想要实现的目标的描述?
  • @MichaelDelgado 我添加了上面的示例并试图澄清我在寻找什么,感谢您调查它!
  • 哦!感谢您的澄清 - 现在这是一个完全不同的问题:)
  • 我以为您要求从时间数组与常数匹配的 omega 中进行选择 - 但如果您只是使用索引数组从 omega 中选择,您可以使用 da.sel 执行此操作,如my answer.
  • hmmm - 在重新阅读您的问题几次后,您似乎就快到了,但只需要使用omega_da.sel(time=date_matrix2015)

标签: indexing python-xarray


【解决方案1】:

您可以将da.selda.idxmax 配对以选择沿任意数量维度的最大值的索引

In [10]: omega_da.sel(time=precip_da.idxmax(dim='time'))
Out[10]:
<xarray.DataArray (lat: 10, lon: 10)>
array([[ 17.72211193, -16.20781517,   9.65493368, -28.16691093,
         18.8756182 ,  16.81924325, -20.55251804, -18.36625778,
        -19.57938236, -10.77385357],
       [  3.95402784,  -5.28478105,  -8.6632994 ,   2.46787932,
         20.53981254,  -4.74908659,   9.5274101 ,  -1.08191372,
          9.4637305 , -10.91884369],
       [-31.30033085,   6.6284144 ,   8.15945444,   5.74849304,
         12.49505739,   2.11797825, -18.12861347,   7.27497695,
          5.16197504, -32.99882591],
       ...
       [-34.73945635,  24.40515233,  14.56982584,  12.16550083,
         -8.3558104 , -20.16328749, -33.89051472,  -0.09599935,
          2.65689584,  29.54056082],
       [-18.8660847 ,  -7.58120994,  15.57632568,   4.19142695,
          8.71046261,   9.05684805,   8.48128361,   0.34166869,
          8.41090015,  -2.31386572],
       [ -4.38999926,  17.00411671,  16.66619606,  24.99390669,
        -14.01424591,  19.85606151, -16.87897   ,  12.84205521,
        -16.78824975,  -6.33920671]])
Coordinates:
    time     (lat, lon) datetime64[ns] 2015-01-01 2015-01-01 ... 2015-01-10
  * lat      (lat) int64 0 1 2 3 4 5 6 7 8 9
  * lon      (lon) int64 0 1 2 3 4 5 6 7 8 9

有关详细信息,请参阅 xarray docs on Indexing and Selecting Data 的精彩部分,尤其是 Advanced Indexing 上的部分,其中介绍了使用 DataArrays 作为索引器进行强大的整形操作。

【讨论】:

  • 啊,非常感谢!这正是我想要做的,也是一个如此简单的解决方案。非常感谢您的帮助!
猜你喜欢
  • 2020-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-05
  • 1970-01-01
  • 2022-01-27
  • 2021-10-10
  • 2021-10-26
相关资源
最近更新 更多