【问题标题】:xarray create Dataset from list of lat/lon points (not square!)xarray 从纬度/经度点列表创建数据集(不是正方形!)
【发布时间】:2020-02-11 16:25:58
【问题描述】:

我需要从不规则的纬度/经度列表中创建一个数据集。这些已堆叠成一个“像素”列表,我需要将其拆开并转换回常规的纬度/经度网格。因为网格中每个像素的数据值都不完整,我需要将缺失值填充为np.nan

我无法使用不规则的经纬度点(像素)列表创建 xr.Dataset

 可重现的示例:

 创建我的数据外观示例

注意:数据不完整,形状为(99,),因此我不能简单地重新调整数据以适应独特的纬度/经度。

import numpy as np
import xarray as xr

unique_latitudes = np.arange(0, 10)
unique_longitudes = np.arange(0, 10)
_ = np.array((np.meshgrid(latitudes, longitudes))).T.reshape(-1, 2)

# we don't have a complete grid of pixels
pixels = _[:99]
latitudes = pixels[:, 0]
longitudes = pixels[:, 1]
pixel_id = [i for i in range(len(pixels))]

# there is one missing datapoint (only 99 pixels so can't simply reshape data)
data = np.random.choice([0,1,2], (pixels.shape[0]))
coords = {'pixel': pixels}
dims = ['pixel']

xr.Dataset({'data': (dims, data)})

Out[]:
<xarray.Dataset>
Dimensions:  (pixel: 99)
Dimensions without coordinates: pixel
Data variables:
    data     (pixel) int64 1 1 2 0 1 0 1 1 0 1 1 2 1 ... 2 2 0 0 1 2 1 2 0 1 1 2

这是就我的数据而言。我有一个长度为 99 的数组。但是这些值中的每一个都对应一个纬度和一个经度。

pixels[:5]

Out[]:
array([[0, 0],
       [0, 1],
       [0, 2],
       [0, 3],
       [0, 4]])

 我想要的是带有适当标记的lat/lon 坐标的xr.Dataset

data = np.random.choice([0,1,2], (100)).astype('float')
data = data.reshape(len(unique_latitudes), len(unique_longitudes))
# remember there is one missing data point in the above data
data[np.unravel_index(99, data.shape)] = np.nan

correct_dims = ['lat', 'lon']
correct_coords = {'lat': unique_latitudes, 'lon': unique_longitudes}
correct_ds = xr.Dataset({'data': (correct_dims, data)}, coords=correct_coords)

correct_ds

Out[]:
<xarray.Dataset>
Dimensions:  (lat: 10, lon: 10)
Coordinates:
  * lat      (lat) int64 0 1 2 3 4 5 6 7 8 9
  * lon      (lon) int64 0 1 2 3 4 5 6 7 8 9
Data variables:
    data     (lat, lon) float64 0.0 1.0 0.0 1.0 0.0 2.0 ... 2.0 1.0 1.0 2.0 nan

【问题讨论】:

  • IIUC,您当前的数据很稀疏。你试过stack/unstack吗?
  • 但我无法将二维pixel 属性作为维度分配给原始datasetcoords = {'pixel': pixels}, dims = ['pixel']
  • 否则可以拆垛!
  • 你能先把它转换成多索引吗?这就是你可以取消堆叠的格式

标签: python python-3.x numpy python-xarray


【解决方案1】:

我遇到并解决了与您类似的问题,这就是我登陆此页面的原因。我的解决方案是利用 pandas 数据帧和 xarray 数据数组之间的连接。我不明白您提供的上述数据。但我认为我的逻辑可能适用于您的情况。

第一步是将您的实际数据准备为 pandas 数据框,其中包含纬度、经度和所有其他变量的列。

然后,您可以基于所有“unique_lat”和“unique_lon”的完整组合生成一个 2 列的 pandas 数据框,以表示您的“完整网格”,使用类似:

# construct a full grid
def expand_grid(lat,lon):
    '''list all combinations of lats and lons using expand_grid(lat,lon)'''
    test = [(A,B) for A in lat for B in lon]
    test = np.array(test)
    test_lat = test[:,0]
    test_lon = test[:,1]
    full_grid = pd.DataFrame({'lat': test_lat, 'lon': test_lon})
    full_grid = full_grid.sort_values(by=['lat','lon'])
    full_grid = full_grid.reset_index(drop=True)
    return full_grid

然后使用 pandas 将您的实际数据与您创建的完整网格结合起来。缺失的点将直接用“NAN”填充。

data_onto_full_grid = pd.merge(full_grid, your_actual_data,how='left")

所以现在你已经有了一个数据框,你可以真正重塑并转换为 xarray,最后保存出来。

target_variable_2D = data_onto_full_grid['target_variable'].values.reshape((len(out_lat),len(out_lon)))
target_variable_xr = xr.DataArray(target_variable_2D, coords=[('lat', out_lat),('lon', out_lon)])
target_variable_xr = target_variable_xr.rename("target_variable")
display(target_variable_xr)

你可以使用for循环来处理几个变量并将它们合并到一个xarray中。

# use for loop to convert all variables to xarray data arrays and combine them
var_2D = []
var_xr = []

for i in range(0,len(data_onto_full_grid.columns)):
    print(data_onto_full_grid.columns[i])
    # skip the "lat" and "lon" columns as they are going to be the dimensions in netcdf
    if (i < 2):
        var_2D.append(np.nan)
        var_xr.append(np.nan)
    else:
        var_2D.append(data_onto_full_grid.iloc[:,i].values.reshape((len(out_lat),len(out_lon))))
        var_xr.append(xr.DataArray(var_2D[i], coords=[('lat', out_lat),('lon', out_lon)]))

# provide unique names so you can merge them later
for i in range(len(var_xr)):
    if (i >= 2): 
        var_xr[i] = var_xr[i].rename(data_onto_full_grid.columns[i])

# merge xarrays for all variables into a single one        
results_xr = xr.merge(var_xr[2:len(data_onto_full_grid.columns)])

# check your results
display(results_xr)

# save out to netcdf
results_xr.to_netcdf('results.nc')

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-07-28
    • 1970-01-01
    • 1970-01-01
    • 2012-12-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-15
    • 1970-01-01
    相关资源
    最近更新 更多