繁体   English   中英

xarray.Dataset的PCA转换

[英]PCA transformation of xarray.Dataset

我需要将PCA转换应用于存储为xarray.Dataset并包含nan值的某些Landsat(卫星影像)场景(出于技术原因,给定像素的每个波段均为nan)。

这是创建示例数据集的代码:

import numpy as np
import xarray as xr

# Create a demo xarray.Dataset
ncols = 25
nrows = 50

lon = [50 + x * 0.2 for x in range(nrows)]
lat = [30 + x * 0.2 for x in range(ncols)]
red = np.random.rand(nrows, ncols) * 10000
green = np.random.rand(nrows, ncols) * 10000
blue = np.random.rand(nrows, ncols) * 10000
nir = np.random.rand(nrows, ncols) * 10000
swir1 = np.random.rand(nrows, ncols) * 10000
swir2 = np.random.rand(nrows, ncols) * 10000

ds = xr.Dataset({'red': (['longitude', 'latitude'], red),
                 'green': (['longitude', 'latitude'], green),
                 'blue': (['longitude', 'latitude'], blue),
                 'nir': (['longitude', 'latitude'], nir),
                 'swir1': (['longitude', 'latitude'], swir1),
                 'swir2': (['longitude', 'latitude'], swir2)},
                coords = {'longitude': (['longitude'], lon),
                          'latitude': (['latitude'], lat)})

# To keep example realistic let's add some nodata
ds = ds.where(ds.latitude + ds.longitude < 90)
print(ds)

<xarray.Dataset> Dimensions:    (latitude: 25, longitude: 50) Coordinates:   * longitude  (longitude) float64 50.0 50.2 50.4 50.6
50.8 51.0 51.2 51.4 ...   * latitude   (latitude) float64 30.0 30.2 30.4 30.6 30.8 31.0 31.2 31.4 ... Data variables:
    red        (longitude, latitude) float64 6.07e+03 13.8 9.682e+03 ...
    green      (longitude, latitude) float64 5.476e+03 350.4 7.556e+03 ...
    blue       (longitude, latitude) float64 4.306e+03 2.104e+03 9.267e+03 ...
    nir        (longitude, latitude) float64 1.445e+03 8.633e+03 6.388e+03 ...
    swir1      (longitude, latitude) float64 6.005e+03 7.692e+03 4.004e+03 ...
    swir2      (longitude, latitude) float64 8.235e+03 3.127e+03 674.6 ...

在Internet上搜索后,我尝试实现sklearn.decomposition PCA功能未成功。

我首先将每个2维波段转换为一个维:

# flatten dataset
tmp_list = []
for b in ['red', 'green', 'blue','nir','swir1','swir2']:
    tmp_list.append(ds[b].values.flatten().astype('float64')) 
flat_ds = np.array(tmp_list)

然后,我尝试计算PCA并在没有nan的位置转换原始数据。 我成功生成了一些输出,但与用ArcGIS或Grass生成的输出完全不同。

当我更改位置时,似乎sklearn函数无法处理包含nan的数据。 因此,我从展平的数据集中删除了nan值,这在我缩小展平的PCA结果时会出现问题,因为它不包含原始数据集维度的倍数。

# deflate PCAs
dims = ds.dims['longitude'], ds.dims['latitude']
pcas = xr.Dataset()
for i in range(flat_pcas.shape[0]):
    pcas['PCA_%i' % (i + 1)] = xr.DataArray(np.reshape(flat_pcas[i], dims),
                                          coords=[ds.longitude.values, ds.latitude.values],
                                          dims=['longitude','latitude'])

要恢复这种情况:

  • 是否存在另一种更简单的方法来在xarray.Dataset上实现PCA转换?

  • nan该如何处理?

尝试使用eofs ,可从此处获取: https : //github.com/ajdawson/eofs

他们在文档中说:

透明处理缺失值:计算EOF时,缺失值会自动删除,然后重新插入到输出字段中。

我已经使用过几次,并且发现它的设计非常好。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM