将 pandas 数据框重组为底图的网格

restructuring pandas dataframe into meshgrid for basemap

我正在尝试关注 basemap tutorial for SST and ice analysis。我的输入数据与示例中的数据不同,示例中的数据来自 netCDF4 作为掩码数组。

我有一个 pandas 数据框,例如:

val_df[0:5]
Out[47]:
    lat lon     value
0   0.4 98.7    NaN
1   0.4 98.8    NaN
2   0.4 98.9    0.64
3   0.4 99.0    NaN
4   0.5 98.5    1.23

纬度和经度表示数据点在地图网格上的唯一位置。要创建示例数据框,您可以使用以下代码:

from itertools import product
import pandas as pd
import numpy as np

locations = np.array([x for x in product([1,2,3],[4,5,6])])
data = np.random.random(len(locations))
val_df = pd.DataFrame({'lat':locations[:,0], 'lon':locations[:,1],
                      'value':data})

我之前所做的是获取此数据框,对其进行透视(使用内置的透视函数),以便 lat 列是索引,lon 列是列和价值观就是价值观。然后我可以使用 m.imshow 绘制结果值。

然而,这似乎是一个糟糕的解决方案。 A) pcolormeshimshow 更推荐,原因我不清楚,B) 似乎人们通常使用 meshgrid,然后使用屏蔽数组。但是,我真的不清楚如何根据底图示例将我的数据构建到 meshgrid 和掩码数组中,因为示例中的数据是预先整形的。

当我创建 lats/lons 的 mesh_grid 时,我执行以下操作:

latmin = np.floor(val_df.lat.min())
latmax = np.ceil(val_df.lat.max())
lonmin = np.floor(val_df.lon.min())
lonmax = np.ceil(val_df.lon.max())
lats = np.arange(latmin, latmax, 0.1)
lons = np.arange(lonmin, lonmax, 0.1)
lats_mesh, lons_mesh = np.meshgrid(lats, lons)

但此时我不清楚如何构建和屏蔽 value 列,以便在我将其提供给 pcolormesh 时,这些值出现在网格的正确位置,如下所示:

from mpl_toolkits.basemap import Basemap
m = Basemap(projection='merc'
           , llcrnrlon=lonmin
           , llcrnrlat=latmin
           , urcrnrlon=lonmax
           , urcrnrlat=latmax)
m.drawcoastlines()
m.drawstates()
m.drawcountries()
m.fillcontinents(color='gray', lake_color='white', zorder=0)
m.drawmapboundary(fill_color='white')

pc1 = m.pcolormesh(lons, lats, masked_data, shading='flat', cmap='hot_r', latlon=True)

基本上,我的问题的答案是我需要旋转我的数据框。

val_pivot_df = val_df.pivot(index='lat', columns='lon', values='b_value')

这会旋转数据框,用 NaNs 和 returns 填充没有数据的区域。由于底图不喜欢 pandas 然后我将数据输出为 numpy 数组并绘制它。

lons = val_pivot_df.columns.values
lats = val_pivot_df.index.values

fig, ax = plt.subplots(1, figsize=(8,8))

m = Basemap(projection='merc',
        llcrnrlat=val_df.dropna().min().lat-5
        , urcrnrlat=val_df.dropna().max().lat+5
        , llcrnrlon=val_df.dropna().min().lon-5
        , urcrnrlon=val_df.dropna().max().lon+5
        , resolution='i', area_thresh=10000
        )

m.drawcoastlines()
m.drawstates()
m.drawcountries()
m.fillcontinents(color='gray', lake_color='white')#, zorder=0)
m.drawmapboundary(fill_color='0.3')

x, y = np.meshgrid(lons,lats) 
px,py = m(x,y) 

data_values = val_pivot_df.values
masked_data = np.ma.masked_invalid(data_values)

cmap = plt.cm.viridis

m.pcolormesh(px, py, masked_data, cmap=cmap, vmin=0, vmax=2, shading='flat')

m.colorbar()