首页 > 解决方案 > 如何设置xarray.assign输出的坐标?

问题描述

我一直在尝试根据 xarray 数据集中数据点的纬度坐标创建两个新变量。但是,我似乎只能分配新的坐标。数据集如下所示:

<xarray.Dataset>
Dimensions:  (lon: 360, lat: 180, time: 412)
Coordinates:
  * lon      (lon) float64 0.5 1.5 2.5 3.5 4.5 ... 355.5 356.5 357.5 358.5 359.5
  * lat      (lat) float64 -89.5 -88.5 -87.5 -86.5 -85.5 ... 86.5 87.5 88.5 89.5
  * time     (time) datetime64[ns] 1981-09-01 1981-10-01 ... 2015-12-01
Data variables:
    evapr    (time, lat, lon) float32 ...
    lhtfl    (time, lat, lon) float32 ...
...

到目前为止,我尝试过的是:

def get_latitude_band(latitude):
    return np.select(
        condlist=
        [abs(latitude) < 23.45,
         abs(latitude) < 35,
         abs(latitude) < 66.55],
        choicelist=
        ["tropical",
         "sub_tropical",
         "temperate"],
        
        default="frigid"
    )

def get_hemisphere(latitude):
    return np.select(
        [latitude > 0, latitude <=0],
        ["north", "south"]
    )

    
mhw_data = mhw_data \
    .assign(climate_zone=get_latitude_band(mhw_data.lat)) \
    .assign(hemisphere=get_hemisphere(mhw_data.lat)) \
    .reset_index(["hemisphere", "climate_zone"]) \
    .reset_coords()
            
print(mhw_data)

这让我接近:

<xarray.Dataset>
Dimensions:        (lon: 360, lat: 180, time: 412, hemisphere: 180, climate_zone: 180)
Coordinates:
  * lon            (lon) float64 0.5 1.5 2.5 3.5 4.5 ... 356.5 357.5 358.5 359.5
  * lat            (lat) float64 -89.5 -88.5 -87.5 -86.5 ... 86.5 87.5 88.5 89.5
  * time           (time) datetime64[ns] 1981-09-01 1981-10-01 ... 2015-12-01
Dimensions without coordinates: hemisphere, climate_zone
Data variables:
    evapr          (time, lat, lon) float32 ...
    lhtfl          (time, lat, lon) float32 ...
    ...
    hemisphere_    (hemisphere) object 'south' 'south' ... 'north' 'north'
    climate_zone_  (climate_zone) object 'frigid' 'frigid' ... 'frigid' 'frigid'
...

但是,我想堆叠 DataSet 并将其转换为 DataFrame。我无法这样做,我认为这是因为新变量hemisphere_climate_zone_没有time, lat,lon坐标:

stacked = mhw_data[var].stack(dim=["lon", "lat", "time"]).to_pandas().T

结果是KeyError“lon”。

所以我的问题是:如何将新变量分配给保持原始时间坐标、纬度和经度的 xarray 数据集?

标签: pythonpandaspython-xarray

解决方案


要分配新变量或坐标,xarray 需要知道维度的名称。定义 DataArray 或 Coordinate 的方法有很多种,但最接近您当前使用的方法是提供一个 元组(dim_names, array)

mhw_data = mhw_data.assign_coords(
    climate_zone=(('lat', ), get_latitude_band(mhw_data.lat)),
    hemisphere=(('lat', ), get_hemisphere(mhw_data.lat)),
)

我在这里使用da.assign_coords,它将定义climate_zonehemisphere作为非维度坐标,您可以将其视为有关纬度和数据的附加元数据,但它们本身并不是正确的数据。这也将允许在将单个数组发送给 pandas 时保留它们。

对于堆叠,转换为 pandas 将自动堆叠。以下将返回一个 DataFrame,其中变量/非维度坐标作为列,维度作为 MultiIndex:

stacked = mhw_data.to_dataframe()

或者,如果您想要一个(lat, lon, time)仅针对这些坐标之一索引的系列,您可以始终使用expand_dims

(
    mhw_data.climate_zone
    .expand_dims(lon=mhw_data.lon, time=mhw_data.time)
    .to_series()
)


推荐阅读