Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/364.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何使用DataArray where()函数根据条件从另一个DataArray赋值_Python_Numpy_Python Xarray - Fatal编程技术网

Python 如何使用DataArray where()函数根据条件从另一个DataArray赋值

Python 如何使用DataArray where()函数根据条件从另一个DataArray赋值,python,numpy,python-xarray,Python,Numpy,Python Xarray,我正在与xarray合作,根据另一个数据集的值的条件创建一个新的数据集 输入数据集对象ds_seasure按季节划分,具有如下三个维度 <xarray.Dataset> Dimensions: (latitude: 106, longitude: 193, season: 4) Coordinates: * latitude (latitude) float32 -39.2 -39.149525

我正在与xarray合作,根据另一个数据集的值的条件创建一个新的数据集

输入数据集对象
ds_seasure
按季节划分,具有如下三个维度

    <xarray.Dataset>
    Dimensions:               (latitude: 106, longitude: 193, season: 4)
    Coordinates:
      * latitude              (latitude) float32 -39.2 -39.149525 ... -33.9
      * longitude             (longitude) float32 140.8 140.84792 ... 150.0
      * season                (season) object 'DJF' 'JJA' 'MAM' 'SON'
    Data variables:
        FFDI 95TH PERCENTILE  (season, latitude, longitude) float64 dask.array<shape=(4, 106, 193), chunksize=(4, 106, 193)>

尺寸:(纬度:106,经度:193,季节:4)
协调:
*纬度32-39.2-39.149525-33.9
*经度(经度)浮动32140.8140.84792。。。150
*季节(季节)对象“DJF”“JJA”“MAM”“SON”
数据变量:
FFDI第95百分位(季节、纬度、经度)浮动64 dask.array
我需要创建一个新的数据集,它有三个维度:纬度、经度和时间。纬度和经度应与输入数据集具有相同的坐标,时间坐标应为10年以上的天数

例如,生成的数据集如下所示:

<xarray.Dataset>
Dimensions:    (latitude: 106, longitude: 193, time: 3653)
Coordinates:
  * latitude   (latitude) float32 -39.2 -39.149525 ... -33.950478 -33.9
  * longitude  (longitude) float32 140.8 140.84792 140.89584 ... 149.95209 150.0
  * time       (time) datetime64[ns] 1972-01-01T00:00:00 1972-01-02T00:00:00 1972-01-03T00:00:00 ... 1981-12-30T00:00:00 1981-12-31T00:00:00
Data variables:
    FFDI 95TH PERCENTILE  (time, latitude, longitude) float64 dask.array<shape=(3653, 106, 193), chunksize=(3653, 106, 193)>

尺寸:(纬度:106,经度:193,时间:3653)
协调:
*纬度32-39.2-39.149525-33.950478 -33.9
*经度(经度)浮动32140.8140.84792140.89584。。。149.95209 150.0
*时间日期时间64[ns]1972-01-01T00:00:00 1972-01-02T00:00:00 1972-01-03T00:00:00。。。1981-12-30T00:00:00 1981-12-31T00:00:00
数据变量:
FFDI第95百分位(时间、纬度、经度)float64 dask.array
一天的变量应与该天所在季节的变量相同。这意味着,1972-01-01、1972-02-02和1972-02-28应具有与季节DJF相同的值;1972-04-01、1972-05-02和1972-05-31应具有与季节MAM相同的值


我正在考虑Dataset的where()函数,但不知道从哪里开始

首先,一个音符。创建一个新的数据阵列,每天复制相同的空间数据,持续3个月,可能会占用大量磁盘空间,但意义不大。我宁愿在您每次需要特定日期的数据时查询季节数据数组。 但是,如果您确实需要执行此操作,并且要回答您的问题,我认为最直接的方法是:

  • 首先,创建一个新容器;np.ndarray是一个好主意
  • 然后,建立日期索引
  • 查询原始季节数据数组
  • 最后,使用维度时间创建一个新的DataArray
  • 在下面的示例中,我创建了一个用于测试的季节数据数组。如果我完全理解您的问题,那么您应该能够使用原始数组,而不会在第二部分(创建foo)中做太多更改

    让我们开始吧。首先是进口:

    import xarray as xr
    import numpy as np
    import pandas as pd
    
    创建所需大小的空容器

    data_s = np.zeros((4, 10, 10))
    
    用虚拟值填充它

    data_s[0] = 0.5
    data_s[1] = 0.9
    data_s[2] = 0.8
    data_s[3] = 0.45
    
    创建虚拟坐标

    x = y = np.arange(10)
    
    创建季节索引

    seasons = ["spring", "summer", "autumn", "winter"]
    
    最后,创建DataArray

    bar = xr.DataArray(data_s, coords=[seasons, x, y], dims=['season', 'x', 'y'])
    
    foo = xr.DataArray(data, coords=[dates, x, y], dims=['time', 'x', 'y'])
    
    bar是要从中提取季节值的数据数组。 现在对单个日期重复相同的步骤

    创建一个2000天的容器数组,我们将用每个季度的数据填充该数组

    data = np.ones((2000, 10, 10))
    x = y = np.arange(10)
    dates = pd.date_range('2000-01-01', periods=2000)
    
    这里我假设北方的季节从月的第一天开始(借用自。 当然,您可以轻松编写更好的函数,例如使用一年中的某一天来获取季节

    season = np.array((dates.month %12 + 3)//3)
    
    创建一个字典,将上面的数字转换为以前在bar中指定的季节字符串

    seas_to_num = {1:"spring", 2:"summer", 3:"autumn", 4:"winter"}
    
    我们用在条[season]上找到的值填充每天的数组

    for date, seas in enumerate(season):
        data[date] = bar.sel(season=seas_to_num[seas])
    
    最后,我们创建DataArray

    bar = xr.DataArray(data_s, coords=[seasons, x, y], dims=['season', 'x', 'y'])
    
    foo = xr.DataArray(data, coords=[dates, x, y], dims=['time', 'x', 'y'])
    
    现在选择4月5日,我们得到春天的值

    In [1]: foo.sel(time=pd.to_datetime("5/4/2001"))
    Out[1]: 
    array([[0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9],
       [0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9],
       [0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9],
       [0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9],
       [0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9],
       [0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9],
       [0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9],
       [0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9],
       [0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9],
       [0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9]])
    Coordinates:
    time     datetime64[ns] 2001-05-03
      * x        (x) int32 0 1 2 3 4 5 6 7 8 9
      * y        (y) int32 0 1 2 3 4 5 6 7 8 9
    

    我同意Andrea的观点,即创建一个包含3653个唯一天数的数据集,而该数据集只复制4个不同的季节值,这通常是低效的。如果您能提供更多关于这方面更广泛目标的信息,或许我们可以建议另一种解决方案

    假设您确实想这样做,最快的方法可能是使用xarray的。在下面的内容中,我将假设
    ds
    是您原始帖子中第二个数据集的名称(维度为
    (纬度:106,经度:193,时间:3653)
    ),然后您可以像

    zeros=xr.zeros\u like(ds)
    填充=0.groupby('time.seasure')+ds\u seasure
    
    这一建议的灵感来源于我们通常根据季节气候学计算异常的方法:

    #维度为“time”的原始数据集
    ds=xr.open_数据集(…)
    #气候学具有“季节”维度
    ds_气候学=ds.groubpy('time.season')。平均值(dim='time'))
    #异常具有维度“时间”
    ds_异常=ds.groubpy('时间.季节')-ds_气候学
    
    这与您在此处提出的问题基本相同:。我建议您改进第一个问题,并关闭此问题。可能重复感谢@jhamman。我认为此问题是关于使用where()解决问题,而另一个问题是关于重采样()我不确定哪一个最适合。我目标的目的是,我能够使用该数据集与另一个每小时一次的数据集进行计算,例如1972-01-01T00:00:00 1972-01-02T00:00:00,…等等:(ds_1+ds_2)。我认为使用两个不同时间维度的参数是不可能的。