Python中如何将X/Y/Z数据向量拟合到带X/Y分箱的二维表格
实现思路与代码示例
以下两种实现方案均可直接在Python环境中运行,无需依赖闭源工具,可按需调整参数适配业务场景。
方案1:逆距离加权(IDW)分配汇总(推荐,贴合逆插值需求)
原理为每个散点的Z值会根据与相邻分箱中心的距离反比分配权重,所有散点的加权值累加后得到分箱的Z汇总结果,天然解决散点不落在分箱内的问题。
import numpy as np import pandas as pd from scipy.spatial import cKDTree # 读取示例数据 df = pd.read_csv('your_data.csv', sep=';') points = df[['X', 'Y']].values z_values = df['Z'].values # 自定义X、Y分箱边界,可按需调整 x_bins = np.arange(0, 11, 2) # X分箱规则:0-2、2-4、...、8-10 y_bins = np.arange(10, 51, 10) # Y分箱规则:10-20、20-30、...、40-50 # 计算分箱中心坐标 x_centers = (x_bins[:-1] + x_bins[1:]) / 2 y_centers = (y_bins[:-1] + y_bins[1:]) / 2 grid_x, grid_y = np.meshgrid(x_centers, y_centers) grid_points = np.vstack([grid_x.ravel(), grid_y.ravel()]).T # 构建KD树快速查询每个散点最近的4个分箱中心 tree = cKDTree(grid_points) distances, indices = tree.query(points, k=4) # 计算逆距离权重,添加极小值避免距离为0报错 weights = 1 / (distances + 1e-8) weights /= weights.sum(axis=1, keepdims=True) # 初始化结果矩阵并加权累加Z值 result = np.zeros(grid_x.shape) for i in range(len(points)): for j in range(4): row, col = np.unravel_index(indices[i,j], grid_x.shape) result[row, col] += z_values[i] * weights[i,j] # 转换为带分箱标签的二维表格,行对应Y分箱、列对应X分箱 result_df = pd.DataFrame( result, index=[f'{y_bins[i]}-{y_bins[i+1]}' for i in range(len(y_bins)-1)], columns=[f'{x_bins[i]}-{x_bins[i+1]}' for i in range(len(x_bins)-1)] ) print(result_df)
方案2:先插值再分箱聚合
如果需要更平滑的结果,可以先对散点做二维插值生成连续曲面,再按分箱区间汇总Z值:
import numpy as np import pandas as pd from scipy.interpolate import griddata # 读取示例数据 df = pd.read_csv('your_data.csv', sep=';') points = df[['X', 'Y']].values z_values = df['Z'].values # 自定义分箱边界 x_bins = np.arange(0, 11, 2) y_bins = np.arange(10, 51, 10) # 生成高密度插值网格 grid_x_dense, grid_y_dense = np.mgrid[0:10:100j, 10:50:100j] # 插值方法可选'nearest'(无平滑)、'linear'(线性平滑)、'cubic'(三次平滑,效果最优) z_dense = griddata(points, z_values, (grid_x_dense, grid_y_dense), method='cubic') # 按分箱区间聚合插值结果 result = np.zeros((len(y_bins)-1, len(x_bins)-1)) for i in range(len(y_bins)-1): y_mask = (grid_y_dense >= y_bins[i]) & (grid_y_dense < y_bins[i+1]) for j in range(len(x_bins)-1): x_mask = (grid_x_dense >= x_bins[j]) & (grid_x_dense < x_bins[j+1]) cell_mask = y_mask & x_mask # 聚合方式可选sum、mean等,按需调整 result[i,j] = np.nanmean(z_dense[cell_mask]) # 转换为二维表格 result_df = pd.DataFrame( result, index=[f'{y_bins[i]}-{y_bins[i+1]}' for i in range(len(y_bins)-1)], columns=[f'{x_bins[i]}-{x_bins[i+1]}' for i in range(len(x_bins)-1)] )
参数调整说明
- 直接修改
x_bins和y_bins即可自定义分箱区间、分箱数量 - IDW方案中查询的近邻数量
k可调整,k越大结果平滑度越高 - 插值方案中可替换
method参数适配不同平滑度需求
内容的提问来源于stack exchange,提问作者And
相关产品推荐
相关产品推荐

