python如何将数据写⼊nc_利⽤python如何处理nc数据详解前⾔
这两天帮⼀个朋友处理了些 nc 数据,本以为很简单的事情,没想到⾥⾯涉及到了很多的细节和坑,⽆论是“知难⾏易”还是“知易⾏
难”都不能充分的说明问题,还是“知⾏合⼀”来的更靠谱些,既要知道理论⼜要知道如何实现,于是经过不太充分的研究后总结成此⽂,以记录如何使⽤ python 处理 nc 数据。
⼀、nc 数据介绍
既然 nc 可以⽤来⼀系列的数组,所以经常被⽤来存储科学观测数据,最好还是长时间序列的。
试想⼀下⼀个科学家每隔⼀分钟采集⼀次实验数据并存储了下来,如果不⽤这种格式存储,时间长了可能就需要创建⼀系列的 csv 或者 txt 等,⽽采⽤ nc ⼀个⽂件就可以搞定,是不是很⽅便。
更⽅便的是如果这个科学实验与⽓象、⽔⽂、温度等地理信息稍微沾点边的,完全也可以⽤ nc 进⾏存储, GeoTiff 顶多能多存⼏个波段(此处波段可以认为是⽓象、⽔⽂等不同信号),⽽ nc 可以存储不同波段的长时间观测结果,是不是⾮常⽅便。
可以使⽤ gdal 查看数据信息,执⾏:
即可得到如下信息:
Driver: netCDF/Network Common Data Format
Files:
Size is 512, 512
Coordinate System is `'
Subdatasets:
SUBDATASET_1_NAME=NETCDF:"":T2
SUBDATASET_1_DESC=[696x130x120] T2 (32-bit floating-point)
SUBDATASET_2_NAME=NETCDF:"":PSFC
SUBDATASET_2_DESC=[696x130x120] PSFC (32-bit floating-point)
SUBDATASET_3_NAME=NETCDF:"":Q2
SUBDATASET_3_DESC=[696x130x120] Q2 (32-bit floating-point)
SUBDATASET_4_NAME=NETCDF:"":U10
SUBDATASET_4_DESC=[696x130x120] U10 (32-bit floating-point)
SUBDATASET_5_NAME=NETCDF:"":V10
SUBDATASET_5_DESC=[696x130x120] V10 (32-bit floating-point)
SUBDATASET_6_NAME=NETCDF:"":RAINC
SUBDATASET_6_DESC=[696x130x120] RAINC (32-bit floating-point)
SUBDATASET_7_NAME=NETCDF:"":SWDOWN
SUBDATASET_7_DESC=[696x130x120] SWDOWN (32-bit floating-point)
SUBDATASET_8_NAME=NETCDF:"":GLW
SUBDATASET_8_DESC=[696x130x120] GLW (32-bit floating-point)
SUBDATASET_9_NAME=NETCDF:"":LAT
SUBDATASET_9_DESC=[130x120] LAT (32-bit floating-point)
SUBDATASET_10_NAME=NETCDF:"":LONG
SUBDATASET_10_DESC=[130x120] LONG (32-bit floating-point)
Corner Coordinates:
Upper Left ( 0.0, 0.0)
Lower Left ( 0.0, 512.0)
Upper Right ( 512.0, 0.0)
Lower Right ( 512.0, 512.0)
Center ( 256.0, 256.0)
每⼀个 SUBDATASET 表⽰记录的是⼀种格式的数据(⽓象、⽔⽂等等),如果要想查看此 SUBDATASET 的具体信息,可以执⾏:gdalinfo :SUBDATASET_NAME
此处的 SUBDATASET_NAME 为上⾯的 T2、PSFC 等等,可以得到如下信息:
Driver: netCDF/Network Common Data Format
Files:
Size is 120, 130
Coordinate System is `'
Metadata:
LAT#description=LATITUDE, SOUTH IS NEGATIVE
LAT#FieldType=104
LAT#MemoryOrder=XY
LAT#stagger=
LAT#units=degree_north
Corner Coordinates:
python怎么读csv数据Upper Left ( 0.0, 0.0)
Lower Left ( 0.0, 130.0)
Upper Right ( 120.0, 0.0)
Lower Right ( 120.0, 130.0)
Center ( 60.0, 65.0)
Band 1 Block=120x1 Type=Float32, ColorInterp=Undefined
NoData Value=9.96920996838686905e+36
Unit Type: degree_north
Metadata:
description=LATITUDE, SOUTH IS NEGATIVE
FieldType=104
MemoryOrder=XY
NETCDF_VARNAME=LAT
stagger=
units=degree_north
此处只有⼀个 Band ,每⼀个 Band 记录了⼀个时间点(或者其他区分形式)的⼀条记录,这个记录是⼀个数组。
所以看到这⾥,各位应该已经明⽩了,可以直接使⽤ GDAL 处理 nc 数据,⽐如直接使⽤ gdalwarp 将某个 SUBDATASET 转成 GeoTiff 等等,此处暂且不表,各位只需要查阅⼀下 gdalwarp ⼿册即可知道如何处理。
明⽩了以上信息基本也就清楚了如何处理此数据。
⼆、数据处理
python 是运⽤⾮常⼴泛,⾃然其下各种类库⾮常丰富,专业⼀点的说法就叫⽣态丰富。
2.1 netCDF4
dataset = netCDF4.Dataset('') # open the dataset
这样即可读出整个 nc 中的数据信息,如果需要获取某个 SUBDATASET 只需要使⽤ dataset[SUBDATASET_NAME] 即可,返回的是⼀个三维数组,表⽰不同时间段(或其他区分⽅式下)的数据信息。
我们可以对此数组做各种操作,如求平均值、⽅差等等,⼜让我想起了⼤学⾥的那⼀堆枯燥但⼜让⼈很有兴趣的实验课程。当然,此处如果使⽤ numpy 框架进⾏处理,会起到事半功倍的效果,如求长时间序列下的平均值:
np_arr = np.asarray(dataset[SUBDATASET_NAME])
average_arr = np.average(np_arr, axis=0)
到这⾥跟地信有关的同志都会看出⼀个问题,此框架只能对数据进⾏处理,⽽不能进⾏与位置有关的操作,这就导致数据⽆法变成直⽩的地图可视化效果。其实任何数据都是相通的,我们可以采⽤此种⽅式处理完后转为 GeoTiff 等,当然我们也可以直接采⽤ GeoTiff 的处理流程来进⾏处理。
2.2 rasterio
rasterio 是 Mapbox 开源的空间数据处理框架,功能⾮常强⼤,此处不细说,只表如何处理我们的 nc 数据。
当然第⼀种⽅式就是使⽤ netCDF4 处理完之后,使⽤此框架写⼊ GeoTiff,但是这样不太优雅,⽽且使⽤了两个框架,明显过于⿇烦,我们直接使⽤此框架从读数据开始处理。
此处读的时候就有技巧了,要像采⽤ gdalinfo 读取 SUBDATASET ⼀样来直接读取此 SUBDATASET 数据,如下:
with rio.open(':SUBDATASET_NAME') as src:
a)
dim = a['count'])
即给 open 函数传⼊ :SUBDATASET_NAME,采⽤ ad(range(1, dim + 1)) 可以直接读出此范围内所有 Band (时间点)的信息,范围可以⾃⼰设定,注意从 0 开始,当然也可以仅读取某个 Band 的信息。
这样我们就可以继续将此数据使⽤ numpy 等框架进⾏处理,处理完之后更重要的是要写⼊ GeoTiff 中(直⽩的说就是添加空间信息)。
也很简单,如下即可:
with rio.open(newfile, 'w', **out_meta) as dst:
dst.write_band(1, res_arr)
newfile 为存储路径,res_arr 为计算结果数组,注意尺⼨不要发⽣变化(width*height),out_meta 为⽬标⽂件的元数据描述信息,可以直接将上⾯ a 进⾏简单处理即可。
out_meta =
meta.update({"driver": "GTiff",
"dtype": "float32",
'count': 1,
'crs': 'Proj4: +proj=longlat +datum=WGS84 +no_defs',
'transform': ansform.from_bounds(west, south, east, north, width, height)
})
crs 表⽰⽬标数据空间投影信息,transform 表⽰⽬标⽂件 空间范围信息,可以通过经纬度信息和图像尺⼨等计算得到。
dst.write_band 将数据写⼊对应波段,当然此处也可以写⼊多个波段,根据计算结果⽽定,同样从 1 开始。
三、总结
本⽂简单介绍了 nc 数据的特点及如何使⽤ python 处理 nc 数据。每个⽬标都有多条路可以达到,重
要的是到那条⾃⼰喜欢的和适合⾃⼰的路,然⽽话⼜说回来,即使⾛的不是想要的那条路,不是⼀样可以达到⽬标嘛!所以关键是要到⾃⼰的⽬标。
好了,以上就是这篇⽂章的全部内容了,希望本⽂的内容对⼤家的学习或者⼯作具有⼀定的参考学习价值,如果有疑问⼤家可以留⾔交流,谢谢⼤家对脚本之家的⽀持。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论