Python 如何使用DataArray where()函数根据条件从另一个DataArray赋值
我正在与xarray合作,根据另一个数据集的值的条件创建一个新的数据集 输入数据集对象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
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个月,可能会占用大量磁盘空间,但意义不大。我宁愿在您每次需要特定日期的数据时查询季节数据数组。 但是,如果您确实需要执行此操作,并且要回答您的问题,我认为最直接的方法是:
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)。我认为使用两个不同时间维度的参数是不可能的。