|
+ C1 b1 @8 V/ {
气象海洋领域,常常会涉及到大规模的数据处理,比如高时空分辨率的模式数据、雷达数据和卫星数据等。
. u6 V* J/ U! D* D& ~
: Z) \' M0 B! \) m% J8 i) m 大部分情况,我们一般只会涉及小规模数据处理,对计算效率并不会太过追求。但是当数据量变大时,低效的数据处理所耗费的时间非常明显,因此高效的数据处理方式尤为重要。 1 X4 b9 ]! Y, T' A/ k( Q3 B
% S' H. b ~2 P0 z- [8 k+ E1 O 本篇以拟合一个高维数据的正太分布参数为例,介绍如何使用xarray+dask加速数据处理。 , w5 j8 G7 F w+ G; g; M
: O* B/ v# B; \+ G 数据维度X[time, lev, lat, lon],需要对三维空间每一点,沿着时间维度做正太分布拟合(正太分布拟合只是作为例子,这里可以定义你需要的操作函数)。
1 U" k ?9 `0 I% V 其中几个关键点解释一下:
$ F# I* L" D1 d# {5 p# g1 g! S (1)首先定义拟合正太分布的函数 & i& C- t+ P; a& N* b: E/ P
def norm_fit(data):
$ p. X7 r$ w. f. {% L; a2 y0 R loc, scale = st.norm.fit(data)! b+ c. r5 I: z. H6 N
return np.array([loc, scale])
8 ]& o% ~2 k. [( t 这里需要注意的是,拟合的函数,输出参数,需要打包为一个数组。并且它的维度需要和后面aplly_ufun定义的输出维度一致。 6 x) O! z" K' n4 V
(2)xarray分块 0 J, T7 F7 M9 l2 [" t
x = xr.DataArray(rs.randn(500, 20, 1500, 1500), dims=["time", "lev", "lat","lon"])& e# I1 V3 e8 x( r: Q
x = x.chunk({"lev":5, "lat":100,"lon":100}) ( g: {2 v* r& D, O
xarray结合dask可以将一个大型数组分成一个个数据块(chunk),需要注意的是我们需要沿着时间维操作,拟合需要整个时间维度的数据,因此时间维time不能分块,只能对其他维度分块。
$ |+ A8 h1 f' s* j& r6 | (3)xarray.apply_ufunc函数
# X) e+ k" R: N result = xr.apply_ufunc(norm_fit,
0 ^5 u5 s6 J: L x,
& \" d# S k: o4 ~% C input_core_dims=[["time"]],# o; ~& ]8 P! X$ Y
output_core_dims=[["paras"]],; Y; {) q% l7 q$ F. B
dask="parallelized",
: f8 y! [$ Z3 L3 ]" X) k3 z output_dtypes=[np.float],1 [0 A; K- C; q
dask_gufunc_kwargs={output_sizes:{"paras":2}}
: F. Q! `6 f5 w2 M5 W ) : d% c8 j/ K6 k3 A, _2 q; }
apply_ufunc函数具体可以参考官网教程,这里只说使用时遇到的困难,即如何定义输出维度:输出维度是用output_core_dim定义的,将输出的拟合参数(期望和标准差)定义为paras维度,维度的大小为2,通过output_sizes参数设置。这样我们输入[time, lev, lat, lon]的数据,在每个空间点对时间维度拟合之后,输出的数据为[lev, lat, lon, paras]。(PS: 这里感谢深雨露大佬的指点) 4 T( M" ]! ~& ^* p5 X/ D- ~
3 s8 x' T& z' J' P( g, k; _ 以下是全部代码: 9 v1 d a$ g4 e2 B' w$ Q& N
from scipy import stats as st
$ ]% w' J) F2 o: {1 U N1 G
3 l; B2 ~0 [5 C- p" Z1 X# ~% r- l import xarray as xr
% Y& S, |$ W! R0 L3 A* n import dask0 B& z. ?5 V8 p* r- ]: X
import numpy as np
5 K7 W. R Q: M9 D from dask.diagnostics import ProgressBar
$ u( q0 K V% N* v' Y% C/ P7 O* p% D7 V2 ^3 n H
def norm_fit(data):
0 C1 f/ P# A# T0 o loc, scale = st.norm.fit(data)3 p9 E) ]1 Y9 g4 f& A# h* n0 E
return np.array([loc, scale])
# u4 j0 s* S! i" i% Q, h( a. e
8 A: U) \- v: k W5 m5 F! E; g# |% K rs = np.random.RandomState(0)
) _/ X. |# N) r' T* e x = xr.DataArray(rs.randn(500, 20, 1500, 1500), dims=["time", "lev", "lat","lon"])' V6 u8 W5 K8 P7 F. l# z
x = x.chunk({"lev":5, "lat":100,"lon":100})
5 R; i S. Y, l& O! r' A
5 Y8 H, B- N" N; W; q, R #使用apply_ufunc计算,并用dask的并行计算
. Z2 A# U/ I9 f4 Q! ] result = xr.apply_ufunc(norm_fit,+ i' V6 D' T# e7 Q& r
x,
; ^; z, Q% f' D! A3 l( R g input_core_dims=[["time"]],9 J6 T& ]0 P- B7 y5 k3 D* i3 l' ?
output_core_dims=[["paras"]],5 ^; A& o# j) q& _/ E
dask="parallelized",: @5 _. K" a& e, _
output_dtypes=[np.float],
6 c; {2 j' F& M* u0 c dask_gufunc_kwargs={output_sizes:{"paras":2}}
4 } E0 |+ e( Q8 j0 U )
l v$ t7 C' ?& \6 p0 Y6 H0 p \: B7 l) f+ J
#compute进行真实的计算并显示进度5 b) ^, i: g2 M% x/ m4 C
with ProgressBar():7 l0 ^% F. j1 w4 S0 q
result = results.compute()
- i0 U1 ~$ \" n1 M/ | p- [, A) z
4 {' A% D& M. N# b( R T) W #结果冲命名保存到nc文件6 G o) e: y$ y; l* |
result = result.rename("norm_paras")
' O3 V- [5 J( o& K% |8 P result = result.to_netcdf("norm_fit_paras.nc",compute=False)' v, C+ z: N/ v# v2 s% j. u
with ProgressBar():
5 x# j2 h* O% @; G% Z$ n' f result.compute()
E# v' r& r; V% A# f 转自:气海同途
: A! q+ z6 k3 y! B# [ 关注【Ai尚研修科研技术平台】公众号,查看更多课程安排及免费数据资料
4 \+ f( {3 H. E6 b
8 C+ h$ J3 G: W5 o$ |* X1 ] 推荐: 1 O g! C# g. g! m* V1 `* o
1、Python语言在地球科学领域中的应用实践技术应用 " K5 u4 w- D8 ~2 }, q* Z; A' n
2、【夏令营】针对课题组人员AI培养计划:“开启AI科研之路” & ~7 k9 Z# e) [* ~" I6 |$ h
3、Python在气象与海洋中的实践技术应用精品课程 & a: W- k9 ~" ~8 k
4、Python在WRF模型自动化运行及前后处理中的实践技术应用
, K; E4 s7 C7 T 5、全套Python机器学习核心技术与案例分析实践应用视频 9 E) }% e9 o3 q0 W7 F; k
6、全套区域高精度地学模拟-WRF气象建模、多案例应用与精美制图精品课程
$ O J4 t4 C- Y7 F3 d* t 7、WRF DA资料同化系统理论、运行与与变分、混合同化新方法技术应用视频教程 1 u5 @5 C2 y3 m' D* d
! f+ j' x$ o( I" R: V
5 t* o9 n' O& _
- i X/ s9 }" m* S/ z0 p( `6 Q* l( C/ y
|