我需要访问一些grib文件。我已经弄明白了如何使用pygrib。 但是,我弄清楚如何做到这一点的唯一方法就是非常缓慢。
我有34年的3小时数据,每年约有36个文件(每10天一个或多或少)。共计约1000个文件。
每个文件都有~80个“消息”(每天8个值,持续10天)。 (它们是空间数据,因此它们具有(x,y)维度)。
要阅读我写的所有数据:
grbfile = pygrib.index(filename, 'shortName', 'typeOfLevel', 'level')
var1 = grbfile.select(typeOfLevel='pressureFromGroundLayer', level=180, shortName='unknown')
for it in np.arange(len(var1)):
var_values, lat1, lon1 = var1[it].data()
if (it==0):
tot_var = np.expand_dims(var_values,axis=0)
else:
tot_var = np.append(tot_var, np.expand_dims(var_values,axis=0),axis=0)
并为1000个文件中的每个文件重复此操作。
有更快的方法吗?比如一次加载每个grib文件的所有~80层?类似的东西:
var_values, lat1, lon1 = var1[:].data()
答案 0 :(得分:1)
如果我理解正确,您希望将每个文件中所有80条消息的数据堆叠在一个数组中。
我必须警告你,那个数组会变得非常大,并且可能会导致NumPy抛出一个MemoryError
(之前发生在我身上),具体取决于你的网格大小等。
话虽这么说,你可以这样做:
# substitute with a list of your file names
# glob is a builtin library that can help accomplish this
files = list_of_files
grib = pygrib.open(files[0]) # start with the first one
# grib message numbering starts at 1
data, lats, lons = grib.message(1).data()
# while np.expand_dims works, the following is shorter
# syntax wise and will accomplish the same thing
data = data[None,...] # add an empty dimension as axis 0
for m in xrange(2, grib.messages + 1):
data = np.vstack((data, grib.message(m).values[None,...]))
grib.close() # good practice
# now data has all the values from each message in the first file stacked up
# time to stack the rest on there
for file_ in files[1:]: # all except the first file which we've done
grib = pygrib.open(file_)
for msg in grib:
data = np.vstack((data, msg.values[None,...]))
grib.close()
print data.shape # should be (80 * len(files), nlats, nlons)
这可能会让你获得一些速度。 pygrib.open
个对象就像生成器一样,因此它们会在调用它时传递每个pygrib.gribmessage
对象,而不是像select()
的{{1}}方法那样构建它们的列表。如果您需要特定文件中的所有消息,那么这就是我访问它们的方式。
希望它有所帮助!