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

修复SciPy RBF插值中NumPy矩阵奇异性:保留最小y值

解决重复输入条目对应的最小y值提取问题(NumPy高效实现)

针对你的需求,以下是两种纯NumPy的高效实现方案,均避免手动遍历,适合处理大规模数据:

方法一:利用np.unique逆索引分组求最小值

通过逆索引将原始数据分组,再对每组计算y的最小值,是处理此类分组聚合问题的经典高效方式:

import numpy as np
from scipy.interpolate import Rbf

# 先将输入列表转换为NumPy数组(若原本已是数组可跳过)
x1 = np.array(x1)
x2 = np.array(x2)
x3 = np.array(x3)
y = np.array(y)

# 合并三个输入数组为(N, 3)的二维数组,每一行代表一个输入条目
points = np.column_stack((x1, x2, x3))

# 获取唯一输入条目,以及每个原始条目对应的唯一组索引
unique_points, inverse_idx = np.unique(points, axis=0, return_inverse=True)

# 按组索引排序,为分组计算做准备
sorted_indices = np.argsort(inverse_idx)
sorted_y = y[sorted_indices]
sorted_inverse = inverse_idx[sorted_indices]

# 找到每个唯一组的分界位置
split_positions = np.where(sorted_inverse[1:] != sorted_inverse[:-1])[0] + 1
split_positions = np.concatenate(([0], split_positions))

# 对每组计算最小y值
min_y = np.minimum.reduceat(sorted_y, split_positions)

# 生成去重后的RBF插值
spline = Rbf(unique_points[:, 0], unique_points[:, 1], unique_points[:, 2], min_y)

方法二:先排序再去重(逻辑更简洁)

通过先按输入条目排序,再按y值升序排序,确保同一输入条目下y最小的项排在最前,再过滤重复项:

import numpy as np
from scipy.interpolate import Rbf

# 转换为NumPy数组并合并输入条目
x1 = np.array(x1)
x2 = np.array(x2)
x3 = np.array(x3)
y = np.array(y)
points = np.column_stack((x1, x2, x3))

# 排序规则:先按x1、x2、x3排序,再按y升序排序(保证同一输入条目下最小y优先)
sort_order = np.lexsort((y, x3, x2, x1))
sorted_points = points[sort_order]
sorted_y = y[sort_order]

# 生成掩码:标记每个唯一输入条目的第一个出现项(即对应最小y的项)
unique_mask = np.concatenate(([True], np.any(sorted_points[1:] != sorted_points[:-1], axis=1)))

# 提取去重后的输入条目和对应最小y值
unique_points = sorted_points[unique_mask]
min_y = sorted_y[unique_mask]

# 创建RBF插值
spline = Rbf(unique_points[:, 0], unique_points[:, 1], unique_points[:, 2], min_y)

说明

两种方法的时间复杂度均为O(N log N),依赖NumPy内置的高效排序和数组操作,完全适配大数据量场景:

  • 方法一适合需要保留原始唯一条目顺序的场景
  • 方法二逻辑更直观,代码量更少

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 17:12:34