首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >重采样xarray对象以降低空间分辨率

重采样xarray对象以降低空间分辨率
EN

Stack Overflow用户
提问于 2018-12-21 14:07:54
回答 4查看 8.9K关注 0票数 14

使用x数组重采样以降低空间分辨率

我希望将xarray对象重采样到更低的空间分辨率(更小的像素)。

代码语言:javascript
复制
import pandas as pd
import numpy as np
import xarray as xr

time = pd.date_range(np.datetime64('1998-01-02T00:00:00.000000000'), np.datetime64('2005-12-28T00:00:00.000000000'), freq='8D')
x = np.arange(1200)
y = np.arange(1200)

latitude = np.linspace(40,50,1200)
longitude = np.linspace(0,15.5572382,1200)

latitude, longitude = np.meshgrid(latitude, longitude)

BHR_SW = np.ones((365, 1200, 1200))

output_da = xr.DataArray(BHR_SW, coords=[time, y, x])
latitude_da = xr.DataArray(latitude, coords=[y, x])
longitude_da = xr.DataArray(longitude, coords=[y, x])

output_da = output_da.rename({'dim_0':'time','dim_1':'y','dim_2':'x'})
latitude_da = latitude_da.rename({'dim_0':'y','dim_1':'x'})
longitude_da = longitude_da.rename({'dim_0':'y','dim_1':'x'})

output_ds = output_da.to_dataset(name='BHR_SW')
output_ds = output_ds.assign({'latitude':latitude_da, 'longitude':longitude_da})

print(output_ds)

<xarray.Dataset>
Dimensions:    (time: 365, x: 1200, y: 1200)
Coordinates:
  * time       (time) datetime64[ns] 1998-01-02 1998-01-10 ... 2005-12-23
  * y          (y) int64 0 1 2 3 4 5 6 7 ... 1193 1194 1195 1196 1197 1198 1199
  * x          (x) int64 0 1 2 3 4 5 6 7 ... 1193 1194 1195 1196 1197 1198 1199
Data variables:
    BHR_SW     (time, y, x) float64 1.0 1.0 1.0 1.0 1.0 ... 1.0 1.0 1.0 1.0 1.0
    latitude   (y, x) float64 40.0 40.01 40.02 40.03 ... 49.97 49.98 49.99 50.0
    longitude  (y, x) float64 0.0 0.0 0.0 0.0 0.0 ... 15.56 15.56 15.56 15.56
代码语言:javascript
复制
# My question is, how to I resample the following by the x,y coordinates to a 200x200 grid?

This is a REDUCING the spatial resolution of the variable.

What I have tried is the following:

```javascript

output_ds.resample(x=200).mean()

ValueError回溯(最近一次调用)

在()

->1 output_ds.resample(x=200).mean()

重采样中的/home/mpim/m300690/miniconda3/envs/holaps/lib/python2.7/site-packages/xarray/core/common.pyc (self、indexer、skipna、closed、label、base、keep_attrs、**indexer_kwargs)

代码语言:javascript
复制
701         group = DataArray(dim_coord, coords=dim_coord.coords,
代码语言:javascript
复制
702                           dims=dim_coord.dims, name=RESAMPLE_DIM)

-> 703石斑鱼= pd.Grouper(freq=freq,closed=closed,label=label,base=base)

代码语言:javascript
复制
704         resampler = self._resample_cls(self, group=group, dim=dim_name,
代码语言:javascript
复制
705                                        grouper=grouper,

/home/mpim/m300690/miniconda3/envs/holaps/lib/python2.7/site-packages/pandas/core/resample.pyc in init(self,freq,closed,label,how,axis,fill_method,limit,loffset,种类,约定,底部,**kwargs)

1198 .format(公约))

1199

-> 1200 freq = to_offset(freq)

1201

1202 end_types = set('M','A','Q','BM','BA','BQ','W')

/home/mpim/m300690/miniconda3/envs/holaps/lib/python2.7/site-packages/pandas/tseries/frequencies.pyc in to_offset(freq)

代码语言:javascript
复制
174                     delta = delta + offset
代码语言:javascript
复制
175         except Exception:

->176个提高ValueError(libfreqs._INVALID_FREQ_ERROR.format(freq))

代码语言:javascript
复制
177
代码语言:javascript
复制
178     if delta is None:

ValueError:无效频率: 200

代码语言:javascript
复制
But I get the error shown.

How can I complete this spatial resampling for x and y?

##  Ideally I want to do this:

```javascript

output_ds.resample(x=200,y=200).mean()

ValueError回溯(最近一次调用)

在()

->1 output_ds.resample(x=200,y=200).mean()

重采样中的/home/mpim/m300690/miniconda3/envs/holaps/lib/python2.7/site-packages/xarray/core/common.pyc (self、indexer、skipna、closed、label、base、keep_attrs、**indexer_kwargs)

代码语言:javascript
复制
679         if len(indexer) != 1:
代码语言:javascript
复制
680             raise ValueError(

-> 681“重采样仅支持单维。

代码语言:javascript
复制
682             )
代码语言:javascript
复制
683         dim, freq = indexer.popitem()

ValueError:只支持单维重采样。

代码语言:javascript
复制
## NOTE: Real data has different behaviour

this on the test data I have created above. On the real data read in from a netcdf file

```javascript

尺寸:(时间: 368,x: 1200,y: 1200)

坐标:

  • 时间(时间) datetime64ns 1998-01-02 1998-01-10 . 2005-12-28 没有坐标的尺寸: x,y 数据变量: 纬度(y,x) float32 (y,x) float32 . Data_Mask (y,x) float32 . BHR_SW (时间,y,x) float32 . 属性: 气候数据接口版本1.9.5 (http://mpimet.mp.. )。 公约: CF-1.4 公司名称:GLOBALBEDO/Glo. 主要内容:提取原BHR_SW (. metadata_profile:波束 metadata_version: 0.5 气候数据操作员版本1.9.5 (http://mpimet.mp.. )。
代码语言:javascript
复制

我也尝试过类似的方法:

代码语言:javascript
复制
ds.resample(x=200).mean()

/home/mpim/m300690/miniconda3/envs/holaps/lib/python2.7/site-packages/xarray/core/common.pyc in resample(self, indexer, skipna, closed, label, base, keep_attrs, **indexer_kwargs)
    686         dim_coord = self[dim]
    687
--> 688         if isinstance(self.indexes[dim_name], CFTimeIndex):
    689             raise NotImplementedError(
    690                 'Resample is currently not supported along a dimension '

/home/mpim/m300690/miniconda3/envs/holaps/lib/python2.7/site-packages/xarray/core/coordinates.pyc in __getitem__(self, key)
    309         if key not in self._sizes:
    310             raise KeyError(key)
--> 311         return self._variables[key].to_index()
    312
    313     def __unicode__(self):

KeyError: 'x'

任何帮助都非常感谢。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2018-12-28 00:33:51

更新

@clausmichele的回答使用coarsen现在是最好的方法。请注意,粗化现在包括指定所需输出坐标的能力。

原始员额

正如piman314所建议的那样,groupby是在xarray中执行此操作的唯一方法。重采样只能用于日期时间坐标。

由于xarray目前不处理多维groupby,因此必须分两个阶段完成:

代码语言:javascript
复制
# this results in bin centers on 100, 300, ...
reduced = (
    output_ds
    .groupby(((output_ds.x//200) + 0.5) * 200)
    .mean(dim='x')
    .groupby(((output_ds.y//200) + 0.5) * 200)
    .mean(dim='y'))

如果您只想降低数据的采样量,可以使用位置切片:

代码语言:javascript
复制
output_ds[:, ::200, ::200]

或者,使用命名的dims:

代码语言:javascript
复制
output_ds[{'x': slice(None, None, 200), 'y': slice(None, None, 200)}]

最后,还有其他的软件包是专门为与xarray兼容的快速正则化而设计的。xESMF是一个很好的。

票数 13
EN

Stack Overflow用户

发布于 2020-09-18 06:24:11

最近,粗化方法被添加到xarray中,我认为这是空间下采样的最佳方法,尽管不可能使用它设置所需的最终分辨率并使其自动计算。粗化将在不重叠的窗口上执行操作(均值、最大值、最小值等),根据您设置的窗口大小,您将获得所需的最终分辨率。

作者的原始输入数据:

代码语言:javascript
复制
import pandas as pd
import numpy as np
import xarray as xr

​

time = pd.date_range(np.datetime64('1998-01-02T00:00:00.000000000'), np.datetime64('2005-12-28T00:00:00.000000000'), freq='8D')
x = np.arange(1200)
y = np.arange(1200)


latitude = np.linspace(40,50,1200)
longitude = np.linspace(0,15.5572382,1200)
latitude, longitude = np.meshgrid(latitude, longitude)

BHR_SW = np.ones((365, 1200, 1200))

output_da = xr.DataArray(BHR_SW, coords=[time, y, x])
latitude_da = xr.DataArray(latitude, coords=[y, x])
longitude_da = xr.DataArray(longitude, coords=[y, x])
output_da = output_da.rename({'dim_0':'time','dim_1':'y','dim_2':'x'})
latitude_da = latitude_da.rename({'dim_0':'y','dim_1':'x'})
longitude_da = longitude_da.rename({'dim_0':'y','dim_1':'x'})

output_ds = output_da.to_dataset(name='BHR_SW')
output_ds = output_ds.assign({'latitude':latitude_da, 'longitude':longitude_da})
print(output_ds)

​

<xarray.Dataset>
Dimensions:    (time: 365, x: 1200, y: 1200)
Coordinates:
  * time       (time) datetime64[ns] 1998-01-02 1998-01-10 ... 2005-12-23
  * y          (y) int64 0 1 2 3 4 5 6 7 ... 1193 1194 1195 1196 1197 1198 1199
  * x          (x) int64 0 1 2 3 4 5 6 7 ... 1193 1194 1195 1196 1197 1198 1199
Data variables:
    BHR_SW     (time, y, x) float64 1.0 1.0 1.0 1.0 1.0 ... 1.0 1.0 1.0 1.0 1.0
    latitude   (y, x) float64 40.0 40.01 40.02 40.03 ... 49.97 49.98 49.99 50.0
    longitude  (y, x) float64 0.0 0.0 0.0 0.0 0.0 ... 15.56 15.56 15.56 15.56

为了将空间分辨率从1200x1200降低到200x200,我们需要6x6窗口。

代码语言:javascript
复制
output_ds.coarsen(x=6).mean().coarsen(y=6).mean()
# or output_ds.coarsen(x=6,y=6).mean()
<xarray.Dataset>
Dimensions:    (time: 365, x: 200, y: 200)
Coordinates:
  * time       (time) datetime64[ns] 1998-01-02 1998-01-10 ... 2005-12-23
  * y          (y) float64 2.5 8.5 14.5 20.5 ... 1.184e+03 1.19e+03 1.196e+03
  * x          (x) float64 2.5 8.5 14.5 20.5 ... 1.184e+03 1.19e+03 1.196e+03
Data variables:
    BHR_SW     (time, y, x) float64 1.0 1.0 1.0 1.0 1.0 ... 1.0 1.0 1.0 1.0 1.0
    latitude   (y, x) float64 40.02 40.07 40.12 40.17 ... 49.88 49.93 49.98
    longitude  (y, x) float64 0.03244 0.03244 0.03244 ... 15.52 15.52 15.52
票数 13
EN

Stack Overflow用户

发布于 2019-02-04 07:05:41

当您使用已经被CDOs操作的NetCDF文件时,您还可以使用CDO SAMPLEGRID函数或NCOs bilinear_interp函数:

SAMPLEGRID (https://code.mpimet.mpg.de/projects/cdo/embedded/cdo.pdf)不插值,它只删除第n个网格点.

bilinear_interp (http://nco.sourceforge.net/nco.html#Bilinear-interpolation)进行插值。

正如您可能想要的平均值,最大值,不管反照率是多少,您可能会更喜欢NCOs bilinear_interp。但是CDO SAMPLEGRID可以为您提供NOCs bilinear_interp所需的grid_out

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53886153

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档