如何在Bash中计算netcdf文件中时间维度上缺失值的数量总和

7
我有一个netcdf文件,其中数据是经度、纬度和时间的函数。我想使用CDO或NCO计算每个网格单元格中缺失条目的总数,这些缺失条目是在时间维度上汇总的,最好不需要调用R、Python等其他工具。
我知道如何获取缺失值的总数。
ncap2 -s "nmiss=var.number_miss()" in.nc out.nc

作为对这个相关问题的回答: 在 R 中计算 netcdf 文件中缺失值的数量
同时,使用 CDO 可以告诉我在空间上的总和。
cdo info in.nc

但我不知道如何在时间上求和。例如,有没有一种方法可以在ncap2中指定要对number_miss进行求和的维度?

2个回答

2

尽管您正在寻求另一种解决方案,但我想向您展示,借助Python的帮助,只需要一行非常简短的代码就可以找到答案。变量m_data与使用netCDF4包读取的具有缺失值的变量具有完全相同的形状。只需执行一个正确指定轴的np.sum命令,即可得出答案。

import numpy as np
import matplotlib.pyplot as plt
import netCDF4 as nc4

# Generate random data for this experiment.
data = np.random.rand(365, 64, 128)

# Masked data, this is how the data is read from NetCDF by the netCDF4 package.
# For this example, I mask all values less than 0.1.
m_data = np.ma.masked_array(data, mask=data<0.1)

# It only takes one operation to find the answer.
n_values_missing = np.sum(m_data.mask, axis=0)

# Just a plot of the result.
plt.figure()
plt.pcolormesh(n_values_missing)
plt.colorbar()
plt.xlabel('lon')
plt.ylabel('lat')
plt.show()

# Save a netCDF file of the results.
f = nc4.Dataset('test.nc', 'w', format='NETCDF4')
f.createDimension('lon', 128)
f.createDimension('lat', 64 )
n_values_missing_nc = f.createVariable('n_values_missing', 'i4', ('lat', 'lon'))
n_values_missing_nc[:,:] = n_values_missing[:,:]
f.close()

是的,用Python很简洁。点赞这个答案。我想我可能得用Python来做这件事。我可以把字段重新写回到netcdf中。 - ClimateUnboxed
我添加了一段代码,展示了如何保存到netcdf。 - Chiel
Chiel,我喜欢你的答案,它非常简洁明了,但是我将接受的答案更改为更新的NCO解决方案,因为它允许我从命令行执行操作。两个答案都很出色。 - ClimateUnboxed

2
我们在NCO 4.6.7版(2017年5月)中为ncap2添加了missing()函数,以解决这个问题。要统计时间上的缺失值:
ncap2 -s 'mss_val=three_dmn_var_dbl.missing().ttl($time)' in.nc out.nc

这里ncap2将两个方法链接在一起,missing()和对时间维度的总计。2D变量mss_val在out.nc中。下面的响应做了相同的事情,但是在空间上进行平均并通过时间报告(因为我误解了OP)。

旧/过时的答案:

有两种使用NCO/ncap2的方法可以实现此目的,但都不如我所希望的那样优雅。要么调用num_miss()逐个记录地组装答案,要么(我更喜欢的方式)使用布尔比较函数,然后沿着选择的轴使用总运算符:

zender@aerosol:~$ ncap2 -O -s 'tmp=three_dmn_var_dbl;mss_val=tmp.get_miss();tmp.delete_miss();tmp_bool=(tmp==mss_val);tmp_bool_ttl=tmp_bool.ttl($lon,$lat);print(tmp_bool_ttl);' ~/nco/data/in.nc ~/foo.nc
tmp_bool_ttl[0]=0 
tmp_bool_ttl[1]=0 
tmp_bool_ttl[2]=0 
tmp_bool_ttl[3]=8 
tmp_bool_ttl[4]=0 
tmp_bool_ttl[5]=0 
tmp_bool_ttl[6]=0 
tmp_bool_ttl[7]=1 
tmp_bool_ttl[8]=0 
tmp_bool_ttl[9]=2

或者

zender@aerosol:~$ ncap2 -O -s 'for(rec=0;rec<time.size();rec++){nmiss=three_dmn_var_int(rec,:,:).number_miss();print(nmiss);}' ~/nco/data/in.nc ~/foo.nc
nmiss = 0 

nmiss = 0 

nmiss = 8 

nmiss = 0 

nmiss = 0 

nmiss = 1 

nmiss = 0 

nmiss = 2 

nmiss = 1 

nmiss = 2 

谢谢,点赞可以让我在命令行中看到答案,但我希望将答案放在一个二维 netcdf 文件中。我想在 nco 中添加一个超级切片功能,例如 ncap2 -s "nmiss=var.number_miss(x,:,:),这可能会很复杂吧?我对 ncap2 不是很熟悉。 - ClimateUnboxed
我们已经实现并使用了类似的语法(例如,avg=var.avg($lat,$lon))来计算平均值、最大/最小值等,与您建议的类似。我不知道为什么我们没有为number_miss()实现它。既然您提出了这个问题,我们会将其放在待办事项列表中 :) - Charlie Zender
从实施以来,我从未跟进过并表示感谢,这些年来一直非常有用,现在又再次使用它。 - ClimateUnboxed

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接