|
# N/ T* S7 v4 b9 B$ {6 Z 气象海洋领域,常常会涉及到大规模的数据处理,比如高时空分辨率的模式数据、雷达数据和卫星数据等。 / ^/ L( ]* c# S! ]
' A- D; D6 M- @6 o& d0 E9 ~! U
大部分情况,我们一般只会涉及小规模数据处理,对计算效率并不会太过追求。但是当数据量变大时,低效的数据处理所耗费的时间非常明显,因此高效的数据处理方式尤为重要。 9 ^+ A- h: F" W( C4 j6 r4 `: a: f5 h
3 l6 I7 |& G/ ?7 K0 o
本篇以拟合一个高维数据的正太分布参数为例,介绍如何使用xarray+dask加速数据处理。 ' `5 P4 F6 |5 Q0 z0 L/ `) P0 \; L
1 Q `4 g( O% [6 y$ y
数据维度X[time, lev, lat, lon],需要对三维空间每一点,沿着时间维度做正太分布拟合(正太分布拟合只是作为例子,这里可以定义你需要的操作函数)。 9 C2 U, a1 O1 w4 O. d
其中几个关键点解释一下:
4 U+ t5 i, l! L& W3 w* h/ W# p (1)首先定义拟合正太分布的函数
8 u: p) Z5 L( @5 D$ @# D3 y2 B, {8 X def norm_fit(data):
2 F0 \: R6 R' p loc, scale = st.norm.fit(data)+ p, J1 x6 y V( X& ]
return np.array([loc, scale]) 9 t- L+ Q, ~& g9 l3 g
这里需要注意的是,拟合的函数,输出参数,需要打包为一个数组。并且它的维度需要和后面aplly_ufun定义的输出维度一致。 & p2 L1 N! z! g
(2)xarray分块 0 J# w/ Q: G+ Y# p
x = xr.DataArray(rs.randn(500, 20, 1500, 1500), dims=["time", "lev", "lat","lon"])
2 Y1 r3 d1 Q8 H, A x = x.chunk({"lev":5, "lat":100,"lon":100}) * H7 Y: h1 o) H8 T
xarray结合dask可以将一个大型数组分成一个个数据块(chunk),需要注意的是我们需要沿着时间维操作,拟合需要整个时间维度的数据,因此时间维time不能分块,只能对其他维度分块。 8 S4 d: g6 s! C6 {4 _; o
(3)xarray.apply_ufunc函数
/ [8 R; o- x8 @$ p2 d5 C3 } result = xr.apply_ufunc(norm_fit,
7 H5 h* H' F: v9 p( h% s1 a, b x,
. V2 j/ D+ S# Q% Y" r/ e$ V. @ input_core_dims=[["time"]],1 z; J# j: l. R
output_core_dims=[["paras"]],! t) V+ v, M- D3 C1 J
dask="parallelized",# M2 L. k; i( y( ]4 g; h9 @8 K4 F
output_dtypes=[np.float]," u3 Q& j$ h Z3 D6 K3 y' m- U
dask_gufunc_kwargs={output_sizes:{"paras":2}}
( O: X" U, {( X ) 7 A- s* ]) y8 g- v) f
apply_ufunc函数具体可以参考官网教程,这里只说使用时遇到的困难,即如何定义输出维度:输出维度是用output_core_dim定义的,将输出的拟合参数(期望和标准差)定义为paras维度,维度的大小为2,通过output_sizes参数设置。这样我们输入[time, lev, lat, lon]的数据,在每个空间点对时间维度拟合之后,输出的数据为[lev, lat, lon, paras]。(PS: 这里感谢深雨露大佬的指点)
& m; R, p3 Z) s8 }: G$ p- D9 K- U. A* ]/ j: M+ n9 J
以下是全部代码:
3 D% F( f: o- R3 n$ G# ? from scipy import stats as st" ~5 S1 n5 i! }1 n* ]
/ ]. I# r, B% g3 k2 g/ j
import xarray as xr
. Z1 ]0 T3 j" f' V; [ import dask$ e$ b, r5 j' F# J- |2 o
import numpy as np' A( w8 t! T+ [$ ~: M
from dask.diagnostics import ProgressBar
) V: K2 v# G( A6 x3 p; `% K1 {& _1 H: f6 j* P8 v3 I i M; ^& d
def norm_fit(data):. \) s9 u: f/ ^. g( E2 L3 {' l
loc, scale = st.norm.fit(data)
8 m6 |) [( e( e$ Q: ^ return np.array([loc, scale])7 r3 [6 R( u( x _0 p
! h1 g; C S1 z* I" K6 J9 k& p- [
rs = np.random.RandomState(0)
% B, h! V& O8 w. F x = xr.DataArray(rs.randn(500, 20, 1500, 1500), dims=["time", "lev", "lat","lon"])
& f& d9 K* K4 |, X8 u9 L x = x.chunk({"lev":5, "lat":100,"lon":100})# v; C+ P* _1 }9 X
/ |' }; I2 w/ U1 r
#使用apply_ufunc计算,并用dask的并行计算
( F/ U- W7 x5 W; Q2 f9 n result = xr.apply_ufunc(norm_fit,
' t& v/ l9 {' Y x,
% m8 _' M0 U$ g4 `1 w input_core_dims=[["time"]],
- c. x4 ^$ k7 x4 ?8 L output_core_dims=[["paras"]],
% `; X8 J+ q; Z' F# L$ P dask="parallelized",6 x) [2 w6 [; D" s: M$ R6 a, `
output_dtypes=[np.float],0 z1 H% S$ z, n* t% a: n* y$ T% u8 @
dask_gufunc_kwargs={output_sizes:{"paras":2}}" i) j* n2 D3 w% W" n K
)
+ e9 I# \1 k3 y; s+ |- T
+ c c% T2 x( k2 p. @0 N1 t3 u #compute进行真实的计算并显示进度
. B4 l) I' v+ @3 Q5 j with ProgressBar():
( C/ H/ P" e6 g result = results.compute()( L" y4 Q" j% U) {# l, [
; l u- d" e) _" @/ ~& I$ L #结果冲命名保存到nc文件+ F! S6 w& m# X7 m" ~& ^- i! f
result = result.rename("norm_paras")
3 h5 ^: N( m. o$ c& I result = result.to_netcdf("norm_fit_paras.nc",compute=False)3 B4 m4 j% x5 j n" g! L' T
with ProgressBar():
/ { ]4 K$ Z. n+ R: r result.compute() ; Z4 y% `: ]1 y
转自:气海同途
6 S1 h q3 @! i3 K* q1 l 关注【Ai尚研修科研技术平台】公众号,查看更多课程安排及免费数据资料 1 I' u* q, x1 d: u/ V& Q( J! o
/ }" Q4 K5 @7 p1 k+ `' k
推荐: . H. f8 F/ h3 j8 A& M
1、Python语言在地球科学领域中的应用实践技术应用
/ G& ^( ^7 m7 l" c% p* y5 H 2、【夏令营】针对课题组人员AI培养计划:“开启AI科研之路” $ d, | E# _( g
3、Python在气象与海洋中的实践技术应用精品课程
$ P$ ]! P; e% l. s" K3 O' z6 S 4、Python在WRF模型自动化运行及前后处理中的实践技术应用 : z( B* q/ l z# Y! Q6 @& V% d
5、全套Python机器学习核心技术与案例分析实践应用视频 / w* o: O) o( V8 _7 }: {0 G
6、全套区域高精度地学模拟-WRF气象建模、多案例应用与精美制图精品课程
* ?! u% k" ~2 Z# p 7、WRF DA资料同化系统理论、运行与与变分、混合同化新方法技术应用视频教程 5 h l+ Y( _% T
8 ^4 Y( L) G9 d- h) ~4 }
" r$ n# q& z$ M) Q
. ]9 M) t2 P' G$ z+ |% T0 H# h
S/ v0 ^0 W# m3 p) g" \6 Q |