|
: o7 t/ E' n0 @* S$ \. R; z2 _ 气象海洋领域,常常会涉及到大规模的数据处理,比如高时空分辨率的模式数据、雷达数据和卫星数据等。 5 e7 o7 F/ O2 s- w
% L; X+ a4 Y' @+ K
大部分情况,我们一般只会涉及小规模数据处理,对计算效率并不会太过追求。但是当数据量变大时,低效的数据处理所耗费的时间非常明显,因此高效的数据处理方式尤为重要。
4 Q' o4 ?( }6 P0 i7 l0 N: t6 ?
" I$ k: D. F P2 {' @ 本篇以拟合一个高维数据的正太分布参数为例,介绍如何使用xarray+dask加速数据处理。
1 Q% y& _: O! R, C/ M6 V
, X% N; X* a0 L 数据维度X[time, lev, lat, lon],需要对三维空间每一点,沿着时间维度做正太分布拟合(正太分布拟合只是作为例子,这里可以定义你需要的操作函数)。
- Z1 m& w! J; v, U, o: D& E7 I 其中几个关键点解释一下:
6 K$ p1 G4 }* k) h (1)首先定义拟合正太分布的函数 % Z+ r) V4 ~. i
def norm_fit(data):
# p/ b4 w. U, }- f0 D loc, scale = st.norm.fit(data): F z% h/ `$ Y
return np.array([loc, scale])
G9 S5 ^% u$ I1 q+ _ 这里需要注意的是,拟合的函数,输出参数,需要打包为一个数组。并且它的维度需要和后面aplly_ufun定义的输出维度一致。
' P/ G# O' K2 K) j8 { (2)xarray分块
! P5 k7 e* u- R% f! }" L# F: L8 F: P. n x = xr.DataArray(rs.randn(500, 20, 1500, 1500), dims=["time", "lev", "lat","lon"])
1 T4 E; H7 {$ T( m( m x = x.chunk({"lev":5, "lat":100,"lon":100}) ; Q$ {3 Z4 \7 u) k1 Q5 m
xarray结合dask可以将一个大型数组分成一个个数据块(chunk),需要注意的是我们需要沿着时间维操作,拟合需要整个时间维度的数据,因此时间维time不能分块,只能对其他维度分块。 + Y. z; q. G2 u4 j' q* H; O
(3)xarray.apply_ufunc函数
1 [3 t: }0 O: ]( X" Y result = xr.apply_ufunc(norm_fit,
, \; P1 I9 |& D' ~ x,
+ P; X, O' w- x1 y7 X% S R1 L' r input_core_dims=[["time"]],2 W" r* l/ T* \) Y: X
output_core_dims=[["paras"]],* u/ r8 U! t6 i1 R' n
dask="parallelized",
$ I7 G9 `& O5 \( Z output_dtypes=[np.float],4 `2 R; J! O2 s! P+ f! g; A! R
dask_gufunc_kwargs={output_sizes:{"paras":2}}
@7 A$ S& b; F* E )
- \2 O; ?& T2 i1 w apply_ufunc函数具体可以参考官网教程,这里只说使用时遇到的困难,即如何定义输出维度:输出维度是用output_core_dim定义的,将输出的拟合参数(期望和标准差)定义为paras维度,维度的大小为2,通过output_sizes参数设置。这样我们输入[time, lev, lat, lon]的数据,在每个空间点对时间维度拟合之后,输出的数据为[lev, lat, lon, paras]。(PS: 这里感谢深雨露大佬的指点)
m ]- `) o2 W% J6 Y" n8 H) h6 s u* v; u
以下是全部代码:
2 o) ?" k7 R0 E) Z. f2 h from scipy import stats as st
0 h: y" ?6 `3 M5 U+ m3 n) m# A1 [0 q8 ]/ m. g" u3 h; h7 l
import xarray as xr
* z" m5 I9 M! A8 {% P* f: q+ u+ L import dask. o, l5 \2 D! o* J5 F s
import numpy as np' y- E3 U; l3 i! g# Y6 A9 T
from dask.diagnostics import ProgressBar
4 G e/ s- z# X+ G+ i+ ~0 q- Y5 _! j- y n6 G; ?' R
def norm_fit(data):
7 k u, w3 w& c, P* N; M% R# v loc, scale = st.norm.fit(data)9 \9 o+ _7 J: O4 {" _
return np.array([loc, scale])
; r& K" E* J# M5 H1 s/ w3 `- v+ e% M+ C1 y+ k1 R4 b, D" x) h9 l
rs = np.random.RandomState(0)
6 L2 |' f- K0 X$ _/ N x = xr.DataArray(rs.randn(500, 20, 1500, 1500), dims=["time", "lev", "lat","lon"])4 s9 o: P2 S3 E0 Q5 H3 d+ A
x = x.chunk({"lev":5, "lat":100,"lon":100})
( W+ \- o5 H" v: \0 E. n4 I2 X9 c2 \0 w+ H6 `6 b7 ? ~
#使用apply_ufunc计算,并用dask的并行计算
4 }% ?0 H. s9 I7 X# Y! F* l result = xr.apply_ufunc(norm_fit,4 h9 S. j3 q- u% m G
x,9 z0 D/ E5 X5 D
input_core_dims=[["time"]],
n# K$ N) o0 Q6 Y9 W output_core_dims=[["paras"]],3 ^4 x7 j) Z! t# r g
dask="parallelized",7 j) q* W2 o# s/ q4 J
output_dtypes=[np.float],5 Q5 M* p2 F) ?0 ?
dask_gufunc_kwargs={output_sizes:{"paras":2}}+ f3 c0 X9 Q s# x1 U
)
: u0 c. L' Q, y
3 L B0 N: h7 x% S$ f: w #compute进行真实的计算并显示进度
( O2 i# D& B' [ with ProgressBar():6 \# H0 f/ h4 o& Y. ^ y! F
result = results.compute()
/ h" _# R! D/ \' |. V4 M5 ]& T [ u' B3 P4 \1 Q# |
#结果冲命名保存到nc文件
( |5 U0 G' g5 l2 R0 _1 J) l& `/ ] result = result.rename("norm_paras")" \, G& x# ^/ c% z% U3 C8 e0 \
result = result.to_netcdf("norm_fit_paras.nc",compute=False)
: _7 {1 j% P1 O; t! u6 s) z, t7 | with ProgressBar():
" h* N& o9 `8 p6 ]1 I result.compute()
: u( y$ W9 q( U4 p0 O E( d+ ~ 转自:气海同途
' G+ W/ G ?4 U6 v$ D1 x+ g: U 关注【Ai尚研修科研技术平台】公众号,查看更多课程安排及免费数据资料
3 E) d, T/ z2 [* T& C# j, W
7 S; \3 {+ y' b. n" X) w. c. \' @0 p 推荐:
" U5 E: |7 C) G1 S. P! i3 e" R 1、Python语言在地球科学领域中的应用实践技术应用 6 s7 I2 X2 d9 ` E
2、【夏令营】针对课题组人员AI培养计划:“开启AI科研之路”
. ?# f( |: k; q0 s- M 3、Python在气象与海洋中的实践技术应用精品课程 , M) [: w6 o% ^5 o
4、Python在WRF模型自动化运行及前后处理中的实践技术应用 7 N. u6 r' d8 Q% q( U
5、全套Python机器学习核心技术与案例分析实践应用视频
5 e, t, ^" M1 z, r- B2 @- M 6、全套区域高精度地学模拟-WRF气象建模、多案例应用与精美制图精品课程
, e6 F' }5 M; d 7、WRF DA资料同化系统理论、运行与与变分、混合同化新方法技术应用视频教程
! w4 R0 x' E% h0 B& U
. x0 [, }) s3 r0 B6 Y. h8 Y- @6 x" K% `
- x, P& l) u* M6 C% }$ a) W" U2 s" W- y
|