【问题标题】:Find the median of many variables in a set of netCDF files in python ( 5 giga of data)在python中找到一组netCDF文件中许多变量的中位数(5 giga数据)
【发布时间】:2019-11-12 20:42:37
【问题描述】:

我在许多 netCDF 文件中注册了数据(大约 5 giga)(两年内每天一个文件)。在这些文件中有 17 个变量,我想找到这些变量的中位数。 我试图连接来自不同数据的每个变量的列表以找到中位数,但我的计算机崩溃了(我总共有 730 个文件。我有 17 个变量,每个变量的维度为 86400) 请问有什么有效的方法来做到这一点。我试过 MFDataset 但它也崩溃了 谢谢

list_of_paths = glob.glob('path/**/*.nc', recursive=True)

time = list(())
a = list(())
b = list(())
c = list(())
d = list(())
e = list(())
f = list(())
g = list(())
h = list(())
i = list(())
j = list(())
k = list(())
l = list(())
m = list(())
n = list(())
o = list(())
p = list(())


for  path in list_of_paths:
      nc=Dataset(path)      
      a.extend(list((nc.variables['c1twa-a'])))  
      b.extend(list((nc.variables['c1twa-b'])))
      c.extend(list((nc.variables['c1twa-c'])))
      d.extend(list((nc.variables['c1tu1-a'])))
      e.extend(list((nc.variables['c1tu1-b'])))
      f.extend(list((nc.variables['c1tu2-a'])))
      g.extend(list((nc.variables['c1tu2-b'])))
      h.extend(list((nc.variables['c1tu2-c'])))
      i.extend(list((nc.variables['c1tu3-a'])))
      j.extend(list((nc.variables['c1tu3-b'])))
      k.extend(list((nc.variables['c1tu4-a'])))
      l.extend(list((nc.variables['c1tu4-b'])))
      m.extend(list((nc.variables['c1tu5-a'])))
      n.extend(list((nc.variables['c1tu5-b'])))
      o.extend(list((nc.variables['c1tu6-a'])))
      p.extend(list((nc.variables['c1tu6-b'])))

然后我寻找每个变量列表的中位数

【问题讨论】:

  • 我认为xarray是你的朋友,它打开5GB数据应该没有问题(它用Dask读取/处理数据,所以内存使用通常不是问题)。

标签: python file bigdata netcdf median


【解决方案1】:

我不确定这是否可行,因为您的数据的内存需求似乎相当大,但理论上,如果您的文件具有类似

的名称格式
data_19810101.nc, data_19810102.nc   

等,即您可以使用带有

的通配符列出它们
ls data_*.nc 

然后您可以使用以下命令从命令行计算中位数:

cdo enspctl,50 data_*.nc median_output.nc

正如我所说,您可能有记忆问题。此外,cdo 需要同时打开所有文件,并且在某些系统上,打开文件的最大数量限制为 256。也许您想先在较少数量的文件上尝试该命令,或者只尝试一年 例如

cdo enspctl,50 data_2005*.nc median_output_2005.nc

顺便说一句,使用 ens 命令还可以轻松计算文件的其他统计信息

cdo ensmax
cdo ensmin
cdo ensmean
cdo ensvar

举几个例子。

【讨论】:

  • 感谢您的回复,我在windows上使用我的实验室电脑和anaconda,我不知道我是否可以在windows上使用cdo,如果可以的话,以哪种方式。
  • 如果您有 Windows 10,现在将 linux 作为子系统直接安装非常容易。不需要wineservers,不需要cgywin,很漂亮!只需快速搜索一下(这里有一个示例windowscentral.com/how-install-linux-distros-windows-10),然后就可以走了。 linux 是纯的,所以你可以用通常的方式在那里安装任何东西:例如 sudo apt-get install cdo。我现在其实是在windows机器上直接在linux系统下运行python的。
  • 我曾经在windows 7上使用wubix,但现在我不能,因为它是实验室机器,不是我的,所以最小的软件应该经过n个人的批准。我什至不在管理会话中。 ://
  • 对 windows 7 道歉我不知道......那么你需要一个 wineserver 或决斗启动......无论如何,如果你有 python 工作,Bart 的解决方案应该可以解决问题并且是更少的内存占用(我为他的 soln 做了 +1,它也使用你选择的语言)。
【解决方案2】:

一个(非常..)最小的例子,使用 xarray 和 numpy。 xarray 可以使用 Dask 以块的形式读取/处理数据,因此过多的内存使用通常不是问题。

import xarray as xr
import numpy as np

f = xr.open_mfdataset('ERA5_land_201812*.nc', combine='by_coords')

u10_median = np.median( f['u10'] )
v10_median = np.median( f['v10'] )
# et cetera..

对于您的问题(使用递归 glob),类似这样的方法可能有效:

import xarray as xr
import numpy as np
import glob

list_of_paths = glob.glob('path/**/*.nc', recursive=True)
f = xr.open_mfdataset(list_of_paths, combine='by_coords')

c1twa_a_median = np.median( f['c1twa-a'] )
# et cetera..

【讨论】:

  • 我试过了,我得到这个错误 ValueError: Could not find any dimension coordinates to used to order the datasets for concatenation
  • 您可能必须在xr.open_mfdataset() 中指定concat_dim。见xarray.pydata.org/en/stable/generated/…
  • 我的变量的维度是文件中提到的时间变量的维度(我试过 concat_dim='time' 和 concat_dim=86400 这是时间的维度,但我一直收到同样的错误)对不起我的基本问题我是python的初学者,这是我的第一次练习,再次感谢您的帮助:)
猜你喜欢
  • 2022-11-19
  • 2016-02-15
  • 2021-05-19
  • 2021-11-14
  • 1970-01-01
  • 2023-04-03
  • 1970-01-01
  • 2021-02-25
  • 2013-04-26
相关资源
最近更新 更多