使用xarray聚合点

问题描述 投票:0回答:1

我有一组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来更高效的完成?

python numpy netcdf python-xarray
1个回答
1
投票

你应该可以用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()

0
投票

我用@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']```
© www.soinside.com 2019 - 2024. All rights reserved.