You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Pandas将300m分辨率土地覆盖数据集降尺度至3000m

300m土地覆盖数据降尺度至3000m的聚合实现方案

一、网格对应关系梳理

3000m是300m的10倍分辨率,每个目标3000m区块对应10×10个原始300m格点。你筛选的1×1度区域中,原始数据每度对应360个300m格点(64800总纬度格数/180度=360,129600总经度格数/360度=360),因此该区域可分成36×36个3000m区块。

二、基于Pandas DataFrame的聚合步骤

假设你的DataFrame命名为df,包含lat、lon、lccs_class列:

1. 给原始格点分配区块ID

通过计算区块经纬度步长,将每个格点映射到所属区块:

# 计算原始300m格点的经纬度间隔
lat_step = df['lat'].diff().dropna().unique()[0]
lon_step = df['lon'].diff().dropna().unique()[0]

# 3000m区块对应的经纬度步长为原始的10倍
block_lat_step = lat_step * 10
block_lon_step = lon_step * 10

# 生成区块ID:用floor除法完成格点到区块的映射
df['lat_block'] = (df['lat'] - df['lat'].min()) // block_lat_step
df['lon_block'] = (df['lon'] - df['lon'].min()) // block_lon_step

2. 聚合主导类并处理多众数情况

按区块分组取lccs_class的众数,同时解决多个类出现次数相同的场景:

def get_dominant_class(series):
    counts = series.value_counts()
    max_count = counts.max()
    # 提取所有出现次数等于最大值的候选类
    candidates = counts[counts == max_count].index.tolist()
    # 选择数值最小的类作为默认结果(可根据业务需求改为随机选或其他规则)
    return min(candidates)

# 按区块分组聚合,得到每个3000m区块的主导类
blocked_result = df.groupby(['lat_block', 'lon_block'])['lccs_class'].agg(get_dominant_class).reset_index()

三、实现“参考周边9个区块”的优化逻辑

若需结合目标区块的8个邻域区块优化多众数判断,可按以下步骤操作:

1. 获取初步区块主导类

# 先通过基础方法得到所有区块的初步结果
blocked_result = df.groupby(['lat_block', 'lon_block'])['lccs_class'].agg(get_dominant_class).reset_index()
# 设置索引方便邻域查找
blocked_result = blocked_result.set_index(['lat_block', 'lon_block'])

2. 编写邻域类ilder闸以Frequently区域 [posingXXX原Mar fit库_Lookup,哦不,是邻域类获取函数

def get_neighbor_classes(lat_block, lon_block):
    # 定义8个邻域的偏移量(上下左右+四个对角)
    offsets = [(-1,-1), (-1,0), (-1,1),
               (0,-1),          (0,1),
               (1,-1),  (1,0), (1,1)]
    neighbor_cls = []
    for dlat, dlon in offsets:
        try:
            cls = blocked_result.loc[(lat_block + dlat, lon_block + dlon), 'lccs_class']
            neighbor_cls.append(cls)
        except KeyError:
            # 边界区块无对应邻域,直接跳过
            continue
    return neighbor_cls

3. 重新处理多众数区块

# 找出所有存在多众数的区块
def has_multimode(series):
    counts = series.value_counts()
    return len(counts[counts == counts.max()]) > 1

multimode_blocks = df.groupby(['lat_block', 'lon_block'])['lccs_class'].apply(has_multimode)
multimode_blocks = multimode_blocks[multimode_blocks].index.tolist()

# 逐个调整多众数区块的主导类
for lat_block, lon_block in multimode_blocks:
    # 获取自身的众数候选
    self_counts = df[(df['lat_block'] == lat_block) & (df['lon_block'] == lon_block)]['lccs_class'].value_counts()
    self_candidates = self_counts[self_counts == self_counts.max()].index.tolist()
    # 获取邻域区块的主导类
    neighbor_cls = get_neighbor_classes(lat_block, lon_block)
    
    if not neighbor_cls:
        # 无邻域的边角区块,直接选自身候选中最小的类
        final_cls = min(self_candidates)
    else:
        # 优先选同时在自身候选和邻域中的类,取邻域中出现次数最多的
        neighbor_counts = pd.Series(neighbor_cls).value_counts()
        common_candidates = [cls for cls in self_candidates if cls in neighbor_counts.index]
        if common_candidates:
            final_cls = max(common_candidates, key=lambda x: neighbor_counts[x])
        else:
            # 无共同候选时,仍取自身最小候选(可按需修改规则)
            final_cls = min(self_candidates)
    
    # 更新结果
    blocked_result.loc[(lat_block, lon_block), 'lccs_class'] = final_cls

# 重置索引得到最终结果
blocked_result = blocked_result.reset_index()

四、更高效的xarray直接聚合方案

若数据量较大,无需转成DataFrame,直接用xarray的coarsen方法效率更高:

import xarray as xr

# 假设ds是处理后的xarray数据集,仅保留lccs_class变量
# 按lat和lon方向各取10个格点聚合
coarsened_ds = ds.coarsen(lat=10, lon=10, boundary='trim').agg({'lccs_class': get_dominant_class})

# 如需转成DataFrame
blocked_result = coarsened_ds.to_dataframe().reset_index()

内容的提问来源于stack exchange,提问作者DiMi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 06:15:03