从Python中的大数据集中子集二维纬度,经度和数据(IMS snowcover)

时间:2017-11-09 00:18:47

标签: python arrays numpy matplotlib-basemap

我有一个“简单”的目标,结果很难实现。我有三个二维数组latlondata都有维度(24576,24576)。前两个是变量data的纬度和经度坐标,我试图在地图上绘制。我正在从二进制文件和文本文件的组合中读取所有这些数据,因此任何预处理操作实际上都是不可能的,需要在Python脚本中完成。

鉴于数组的维数,由于存储器的限制,即使在全球范围内的小区域上选择底图投影,也几乎不可能直接绘制数据。我尝试使用basemap.contourf进行绘图时已经尝试过并出现内存错误。

因此,我需要在将数组传递给轮廓函数之前对其进行子集化。我尝试过很多东西,但似乎没什么用。我的想法是做这样的事情

lat_bnds, lon_bnds = [35, 50], [5, 20]
condition=((lats > lat_bnds[0]) & (lats < lat_bnds[1])) & (lons > lon_bnds[0]) & (lons < lon_bnds[1])

latslons是2-D坐标数组。这产生了一个2-D布尔数组,其具有与lats(或等效lons)相同的维度,然后我可以使用它来掩盖原始数据但不对其进行子集化。

numpy.where中使用相同的条件会产生一个我不能使用的(2, 2564856)数组。我认为这里的问题是在2-D阵列的每个点都需要满足多个条件,并且不能保证这将导致连续的矩形子矩阵。然而,为了绘制这些数据,我真的需要对它们进行子集化,或者找到另一种方法来详细说明它们。

我错过了一些明显的东西吗?有没有其他智能方法可以绘制原始数据而不会遇到任何错误?

数据来源: http://nsidc.org/data/G02156

在假设您下载了必要文件的情况下阅读数据的简短脚本:

import numpy as np
import pandas as pd
from mpl_toolkits.basemap import Basemap # Import the Basemap toolkit

with open('IMS1kmLats.24576x24576x1.double', 'rb') as f:
 data = np.fromfile(f, dtype='<d', count=24576*24576)
 lats = np.reshape(data, [24576, 24576], order='F')

with open('IMS1kmLons.24576x24576x1.double', 'rb') as f:
 data = np.fromfile(f, dtype='<d', count=24576*24576)
 lons = np.reshape(data, [24576, 24576], order='F')

widths=np.full((24576), 1, dtype=int).tolist()
data=np.array(pd.read_fwf('ims2017312_1km_v1.3.asc', skiprows=30, 
widths=widths, lineterminator='\n', header=None))

2 个答案:

答案 0 :(得分:0)

我不确定你是如何得到那个形状的数组的,但是如果你想要一个原始数组的子集并且你有条件,你可以从原始列表切片。

a = np.random.randint(10,50, size=(50,2))  # ---- generate coordinates

array([[44, 11],
       [40, 36],
       [19, 26],
       ..., 
       [33, 26],
       [42, 12],
       [15, 25]])

lats = a[:, 1]  # ---- latitude is Y-axis
lons = a[:, 0]  # ---- longitude is X-axis
lat_bnds, lon_bnds = [35, 50], [5, 20]  # ---- your desired bounds

condition =((lats > lat_bnds[0]) & (lats < lat_bnds[1])) & 
            (lons > lon_bnds[0]) & (lons < lon_bnds[1])

condition
array([False, False, False, ..., False, False, False], dtype=bool)

condition.shape  # => (50,)

a[condition]     # ---- slice the original array

array([[11, 45],
       [15, 40],
       [15, 43],
       [15, 49]])

希望能让你朝着你想要的方向前进。

答案 1 :(得分:0)

如果有人在尝试使用Python绘制IMS 1-km分辨率数据时遇到这篇文章,我会找到一个可以正常工作的穷人解决方案。

绘图例程引发了内存错误,但数组仍然可以存储到python中。因此,我只是尝试使用像

这样的显式索引,而不是使用where函数进行子集化
lat_subset=lat[imin:imax, jmin:jmax]

然后使用plot.imshow()绘制结果,而不进行等高线图或使用地图投影以了解数据的外观。这使我能够以我感兴趣的区域内部的方式选择指数跨度。现在我能够制作轮廓图而不会出现内存错误。

我有一个带有笔记本的小型存储库,它显示了如何绘制这些数据:https://github.com/guidocioni/snow_ims/blob/mistral/plot_ims.ipynb。 它具有直接在线读取文件的优点,虽然坐标文件仍需要根据其大小下载。