我有一组netcdf数据集,基本上看起来像一个CSV文件,其中有纬度、经度、值等列。这些点是沿着轨道的点,我想把这些点聚集到一个规则的网格中,比如从-90到90,从-180到180度,通过计算所有落在给定单元格中的点的平均值和标准差。
通过一个循环可以很容易地完成这个任务
D = np.zeros((180, 360))
for ilat in np.arange(-90, 90, 1, dtype=np.int):
for ilon in np.arange(-180, 180, 1, dtype=np.int):
p1 = np.logical_and(ds.lat >= ilat,
ds.lat <= ilat + 1)
p2 = np.logical_and(ds.lon >=ilon,
ds.lon <= ilon+1)
if np.sum(p1*p2) == 0:
D[90 + ilat, 180 +ilon] = np.nan
else:
D[90 + ilat, 180 + ilon] = np.mean(ds.var.values[p1*p2])
# D[90 + ilat, 180 + ilon] = np.std(ds.var.values[p1*p2])
除了用numbacython来加快这个速度外,我想知道这是不是可以直接用xarray来更高效的完成?
你应该可以用pandas和xarray来解决这个问题。
你首先需要将你的数据集转换为pandas数据框架。
一旦完成,df是数据框,假设经度和纬度都是lonlat,你需要将lonlats舍入到最接近的整数值,然后计算每个lonlat的平均值。然后你需要将 lonlat 设置为 indices。然后你可以使用xarray的to_xarray来转换为一个数组。
import xarray as xr
import pandas as pd
import numpy as np
df = df.assign(lon = lambda x: np.round(x.lon))
df = df.assign(lat = lambda x: np.round(x.lat))
df = df.groupby(["lat", "lon"]).mean()
df = df.set_index(["lat", "lon"])
df.to_xarray()
我用@robert-wilson作为起点,然后... to_xarray
确实是我解决方案的一部分。其他灵感来自于 此处. 我使用的方法如下图所示。这可能比上面的numba-ing我的解决方案要慢,但简单多了。
import netCDF4
import numpy as np
import xarray as xr
import pandas as pd
fname = "super_funky_file.nc"
f = netCDF4.Dataset(fname)
lat = f.variables['lat'][:]
lon = f.variables['lon'][:]
vari = f.variables['super_duper_variable'][:]
df = pd.DataFrame({"lat":lat,
"lon":lon,
"vari":vari})
# Simple functions to calculate the grid location in rows/cols
# using lat/lon as inputs. Global 0.5 deg grid
# Remember to cast to integer
to_col = lambda x: np.floor(
(x+90)/0.5).astype(
np.int)
to_row = lambda x: np.floor(
(x+180.)/0.5).astype(
np.int)
# Map the latitudes to columns
# Map the longitudes to rows
df['col'] = df.lat.map(to_col)
df['row'] = df.lon.map(to_row)
# Aggregate by row and col
gg = df.groupby(['col', 'row'])
# Now, create an xarray dataset with
# the mean of vari per grid cell
ds = gg.mean().to_xarray()
dx = gg.std().to_xarray()
ds['stdi'] = dx['vari']
dx = gg.count().to_xarray()
ds['counti'] = dx['vari']```