如何在pandas中缩小分辨率为300m x 300x的土地覆盖数据集

weylhg0b  于 2023-09-29  发布在  其他
关注(0)|答案(2)|浏览(105)

我有一个netcdf文件的土地覆盖一年与300米的分辨率。这太详细了,我想把它缩小到大约3 k。
目前我打开.nc文件与xarray这给了我一个数据集:
Dimensions: time: 1 lat: 64800 lon: 129600 bounds: 2
它也有很多变量.我唯一感兴趣的是lccs_class (time, lat, lon)
删除不需要的变量:

ds = ds.drop(['processed_flag', 'current_pixel_state', 'observation_count', 'change_count', 'crs', 'time_bounds'])

我想看看一个特定的1x 1度块-所以我这样设置它:

central_lat = -33.9248685
central_lon = 18.4240553

lat_min = central_lat - 0.5
lat_max = central_lat + 0.5

lon_min = central_lon - 0.5
lon_max = central_lon + 0.5
filtered_ds = ds.sel(lat=slice(lat_max, lat_min), lon=slice(lon_min, lon_max))

我把它转换成一个pandas数据框:

<class 'pandas.core.frame.DataFrame'>
MultiIndex: 259200 entries, (Timestamp('2019-01-01 00:00:00'), -33.42638888888889, 17.92638888888891, 0) to (Timestamp('2019-01-01 00:00:00'), -34.42361111111111, 18.923611111111114, 1)
Data columns (total 3 columns):
 #   Column      Non-Null Count   Dtype  
---  ------      --------------   -----  
 0   lccs_class  259200 non-null  uint8  
 1   lat_bounds  259200 non-null  float64
 2   lon_bounds  259200 non-null  float64
dtypes: float64(2), uint8(1)
memory usage: 5.7 MB

我想缩小以查看3000mx3000m代表性块。
必须有一个已知的技术来做到这一点?
我正在考虑以下方法:
取9块的中点:其中,当(row - 1) % 3 == 0时选择块(x)

0 0 0 0 0 0 0 0 0
0 x 0 0 x 0 0 x 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 x 0 0 x 0 0 x 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 x 0 0 x 0 0 x 0
0 0 0 0 0 0 0 0 0

然后选择周围块中占优势的lccs_class。但如果数量相等呢?
我也不确定如何从数据集中计算x块和周围的块。

b4wnujal

b4wnujal1#

您可以使用iloc进行简单的切片:

sub_df = df.iloc[1::3, 1::3]

输出量:
使用的输入:

0  1  2  3  4  5  6  7  8
0  0  0  0  0  0  0  0  0  0
1  0  x  0  0  x  0  0  x  0
2  0  0  0  0  0  0  0  0  0
3  0  0  0  0  0  0  0  0  0
4  0  x  0  0  x  0  0  x  0
5  0  0  0  0  0  0  0  0  0
6  0  0  0  0  0  0  0  0  0
7  0  x  0  0  x  0  0  x  0
8  0  0  0  0  0  0  0  0  0

对于更一般的方法,如果考虑N*N平方,N是奇数:

N = 3
start = N//2

sub_df = df.iloc[start::N, start::N]

每平方最常见值

你可以使用numpy来进行整形,使用scipy.stats.mode来获得最常见的值:

from scipy.stats import mode

N = 3
start = N//2

out = pd.DataFrame(mode(df.to_numpy().reshape(N, df.shape[0]//N, N, df.shape[1]//N)
                          .swapaxes(1, 2)
                          .reshape(N, N, -1),
                        axis=-1).mode.squeeze(axis=-1),
                   columns=df.columns[start::N], index=df.index[start::N]
                  )

输出量:
使用的输入:

0  1  2  3  4  5  6  7  8
0  a  a  a  b  0  0  0  0  0
1  a  x  a  b  x  b  0  x  0
2  x  x  x  b  0  x  0  0  0
3  0  0  0  0  0  0  0  0  0
4  0  x  0  0  x  0  0  x  0
5  0  0  0  0  0  0  0  0  0
6  0  0  0  0  0  0  0  0  0
7  0  x  0  0  x  0  0  x  0
8  0  0  0  0  0  0  0  0  0
icnyk63a

icnyk63a2#

要使用pandas和提供的代码缩小分辨率为300m x 300m的土地覆盖数据集,您可以执行以下步骤:
重新采样数据集:您可以使用xarray提供的重采样方法将数据集缩小到所需的分辨率。在这种情况下,您需要重新采样到300 m x 300 m分辨率。可以通过在重采样方法中指定纬度和经度因子来实现这一点。

resampled_ds = filtered_ds.resample(lat=0.0027, lon=0.0027).mean()

转换为Pandas DataFrame:如果你想在Pandas DataFrame中使用重采样数据,你可以使用to_DataFrame方法将xarray数据集转换为DataFrame。

df = resampled_ds.to_dataframe()

可选:筛选出NaN值:根据原始数据集和重采样过程,结果DataFrame中可能有NaN值。如果需要,您可以选择过滤掉具有NaN值的行。

df = df.dropna()

现在您有了一个Pandas DataFrame(df),其中包含在指定的纬度和经度范围内缩小到300m x 300m分辨率的土地覆盖数据。您可以根据需要在此DataFrame上执行进一步的数据分析或可视化。

相关问题