前言

这两天帮一个朋友处理了些 nc 数据,本以为很简单的事情,没想到里面涉及到了很多的细节和坑,无论是“知难行易”还是“知易行难”都不能充分的说明问题,还是“知行合一”来的更靠谱些,既要知道理论又要知道如何实现,于是经过不太充分的研究后总结成此文,以记录如何使用 python 处理 nc 数据。

一、nc 数据介绍

既然 nc 可以用来一系列的数组,所以经常被用来存储科学观测数据,最好还是长时间序列的。

试想一下一个科学家每隔一分钟采集一次实验数据并存储了下来,如果不用这种格式存储,时间长了可能就需要创建一系列的 csv 或者 txt 等,而采用 nc 一个文件就可以搞定,是不是很方便。

更方便的是如果这个科学实验与气象、水文、温度等地理信息稍微沾点边的,完全也可以用 nc 进行存储, GeoTiff 顶多能多存几个波段(此处波段可以认为是气象、水文等不同信号),而 nc 可以存储不同波段的长时间观测结果,是不是非常方便。

可以使用 gdal 查看数据信息,执行:

gdalinfo name.nc

即可得到如下信息:

Driver: netCDF/Network Common Data Format

Files: test.nc

Size is 512, 512

Coordinate System is `'

Subdatasets:

SUBDATASET_1_NAME=NETCDF:"test.nc":T2

SUBDATASET_1_DESC=[696x130x120] T2 (32-bit floating-point)

SUBDATASET_2_NAME=NETCDF:"test.nc":PSFC

SUBDATASET_2_DESC=[696x130x120] PSFC (32-bit floating-point)

SUBDATASET_3_NAME=NETCDF:"test.nc":Q2

SUBDATASET_3_DESC=[696x130x120] Q2 (32-bit floating-point)

SUBDATASET_4_NAME=NETCDF:"test.nc":U10

SUBDATASET_4_DESC=[696x130x120] U10 (32-bit floating-point)

SUBDATASET_5_NAME=NETCDF:"test.nc":V10

SUBDATASET_5_DESC=[696x130x120] V10 (32-bit floating-point)

SUBDATASET_6_NAME=NETCDF:"test.nc":RAINC

SUBDATASET_6_DESC=[696x130x120] RAINC (32-bit floating-point)

SUBDATASET_7_NAME=NETCDF:"test.nc":SWDOWN

SUBDATASET_7_DESC=[696x130x120] SWDOWN (32-bit floating-point)

SUBDATASET_8_NAME=NETCDF:"test.nc":GLW

SUBDATASET_8_DESC=[696x130x120] GLW (32-bit floating-point)

SUBDATASET_9_NAME=NETCDF:"test.nc":LAT

SUBDATASET_9_DESC=[130x120] LAT (32-bit floating-point)

SUBDATASET_10_NAME=NETCDF:"test.nc":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 NETCDF:name.nc:SUBDATASET_NAME

此处的 SUBDATASET_NAME 为上面的 T2、PSFC 等等,可以得到如下信息:

Driver: netCDF/Network Common Data Format

Files: test.nc

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:

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('name.nc') # 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('NETCDF:name.nc:SUBDATASET_NAME') as src:

print(src.meta)

dim = int(src.meta['count'])

src.read(range(1, dim + 1))

即给 open 函数传入 NETCDF:name.nc:SUBDATASET_NAME,采用 src.read(range(1, dim + 1)) 可以直接读出此范围内所有 Band (时间点)的信息,范围可以自己设定,注意从 0 开始,当然也可以仅读取某个 Band 的信息。

src.meta 记录了此 SUBDATASET 的元数据信息,与 gdalinfo 看到的基本相同。

这样我们就可以继续将此数据使用 numpy 等框架进行处理,处理完之后更重要的是要写入 GeoTiff 中(直白的说就是添加空间信息)。

也很简单,如下即可:

with rio.open(newfile, 'w', **out_meta) as dst:

dst.write_band(1, res_arr)

newfile 为存储路径,res_arr 为计算结果数组,注意尺寸不要发生变化(width*height),out_meta 为目标文件的元数据描述信息,可以直接将上面 src.meta 进行简单处理即可。

out_meta =

meta.update({"driver": "GTiff",

"dtype": "float32",

'count': 1,

'crs': 'Proj4: +proj=longlat +datum=WGS84 +no_defs',

'transform': rasterio.transform.from_bounds(west, south, east, north, width, height)

})

crs 表示目标数据空间投影信息,transform 表示目标文件 空间范围信息,可以通过经纬度信息和图像尺寸等计算得到。

dst.write_band 将数据写入对应波段,当然此处也可以写入多个波段,根据计算结果而定,同样从 1 开始。

三、总结

本文简单介绍了 nc 数据的特点及如何使用 python 处理 nc 数据。每个目标都有多条路可以达到,重要的是找到那条自己喜欢的和适合自己的路,然而话又说回来,即使走的不是想要的那条路,不是一样可以达到目标嘛!所以关键是要找到自己的目标。

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。

python处理nc文件并输出_利用python如何处理nc数据详解相关推荐

  1. python输入一个整数倒序输出_利用Python实现倒序任意整数

    这是很早以前学习C时候做过的一个练习题,题目的要求大概是把用户输入的三位数倒序输出,比如说用户输入123,然后程序应该输出的结果是321.如果遇到用户输入100,那么程序应该输出1.然后我给扩展一下, ...

  2. Python算法教程第一章知识点:利用插入元素的例子详解list之本质

    声明:由于中译本翻译过于冗余,所以将有用处的知识点罗列出来. 微信公众号:geekkr 本文目录:一.利用插入元素的例子详解list之本质 </br> 一.利用插入元素的例子详解list之 ...

  3. python 16bit转8bit的工具_利用python读取YUV文件 转RGB 8bit/10bit通用

    注:本文所指的YUV均为YUV420中的I420格式(最常见的一种),其他格式不能用以下的代码. 位深为8bit时,每个像素占用1字节,对应文件指针的fp.read(1): 位深为10bit时,每个像 ...

  4. python 表格格式输出_利用python对excel中一列的时间数据更改格式操作

    问题场景:需要将下列的交期一列的数据格式更改成2019/05/10 存货编码 尺寸 数量 交期 0 K10Y0190000X B140 200 2019-05-10 00:00:00 1 K10Y01 ...

  5. python数据库操作批量sql执行_利用Python如何批量修改数据库执行Sql文件

    利用Python如何批量修改数据库执行Sql文件 来源:中文源码网    浏览: 次    日期:2018年9月2日 [下载文档:  利用Python如何批量修改数据库执行Sql文件.txt ] (友 ...

  6. python 替换array中的值_利用Python提取视频中的字幕(文字识别)

    我的CSDN博客id:qq_39783601,昵称是糖潮丽子~辣丽 从今天开始我会陆续将数据分析师相关的知识点分享在这里,包括Python.机器学习.数据库等等. 今天来分享一个Python小项目! ...

  7. python画二维温度云图_利用python画出词云图

    本文将介绍如何利用python中相应的模块画出词云图.首先给出效果图: 其中词云图中的词汇是对手机短信中的垃圾短信的统计,字体越大表示在垃圾短信中出现的频次越高.下面给出具体的步骤. 读取" ...

  8. python中θ符号怎么打出来_利用python打印特殊符号

    原博文 2020-05-02 19:57 − 1.方法一,调用字符映射表输入特殊符号 在键盘上按win+R,在打开的对话框中输入"charmap",会出现字符映射表: 2.利用字符 ...

  9. python获取window共享目录列表_利用Python获取DICOM RTstructure勾画列表

    在<利用Python打开DICOM CT文件>一文中,我们利用pydicom.dcmread()读取了CT图像.本文中我们将修改load_scan()函数来读取RTstructure文件并 ...

最新文章

  1. 022_applescript快速入门教程
  2. 安卓屏幕分辨率及UI尺寸详解
  3. ps怎么更改背景图层大小_PhotoShop处理图层的一些技巧方法、PS图层处理教程
  4. 国风国潮吹到PPT设计,可编辑模板轻松掌握东方韵味
  5. python链表逆序实例_python 单链表翻转的简单示例
  6. matlab语音去除白噪声_matlab去除高斯白噪声
  7. 下行文格式图片_下行文格式图片_写信封的正确格式图片 看完这些你就懂了
  8. 如何将pdf压缩到最小?怎么将pdf文档压缩至更小?
  9. ps:HSB色彩模式
  10. 为什么你要考虑使用Prisma
  11. 分析力学复习笔记(更新中)
  12. 小红书API获得店铺的所有商品,数据接口服务
  13. html背景渲染原理(body透明渐变)
  14. hive获取近12个月数据
  15. 个人邮箱Outlook登录入口在哪,遇到登录邮箱服务器配置错误的解决办法
  16. 1173 Problem V 《C语言程序设计》江宝钏主编-习题6-2-排列数
  17. prometheus-adapter自定义hpa
  18. 005_video_speed_controller
  19. 对空间中6个点两两连线,用红黄两种颜色对这些边染色,则同色的三角形至少有几个?
  20. python赋值法例子_大佬们 我是刚开始学python的小白 遇到这种赋值方式 实在不懂这个a+b是赋值给谁的 求解...

热门文章

  1. how is our class instance registered - thanks to AnnotationConfigWebApplicationC
  2. 使用SAP OData offline库实现Android应用的离线(offline)模式
  3. 在CRM呼叫中心的搜索结果点击Edit按钮后的处理逻辑
  4. ABAP webservice运行时的HTTP 307 redirect重定向是怎么来的
  5. CM: word template web service schema number的限制
  6. UI debug mode
  7. SAP云平台对Kubernetes的支持
  8. SAP云平台,区块链,超级账本和智能合约
  9. 使用JDK自带的工具jstack找出造成运行程序死锁的原因
  10. OpenFOAM安装+ParaView安装+环境配置(deb直接安装详细记录-Ubuntu14.04+OpenFOAM4.1)