如何解决scipy interp1d报'Expect x to not have duplicates'错误
报错根因
scipy.interpolate.interp1d 执行三次(cubic)插值时,底层调用的样条生成函数强制要求输入的自变量x序列无重复值、单调递增。从报错信息可以直接定位:你传入的all_dat['rcs']列存在重复取值,因此触发ValueError: Expect x to not have duplicates异常。
排查步骤
- 校验x列重复值:运行以下代码可以直接统计重复值数量、输出具体重复的取值,确认重复规模:
# 提取所有重复的rcs值(keep=False表示把所有重复条目都标记出来) duplicate_entries = x[x.duplicated(keep=False)] print(f"rcs列共检测到{len(duplicate_entries)}条重复记录,涉及的重复值为:{duplicate_entries.sort_values().unique()}")
- 校验x列单调性:三次插值同样要求x是单调递增序列,去重后如果还是报错可以跑这行确认顺序是否正确:
print(f"rcs列是否为单调递增序列:{x.is_monotonic_increasing}")
解决方案
根据你的数据属性选对应方案即可:
方案1:聚合重复值后插值(适合同一x对应多组有效测量值的场景)
如果同一个rcs值对应多个Mean_Range是正常的多次测量结果,可以先按x分组对y做聚合(取均值、中位数都可以,根据业务需求选),再传入插值函数:
# 按rcs分组聚合Mean_Range,同时排序保证x单调递增 clean_df = all_dat[['rcs', 'Mean_Range']].groupby('rcs', as_index=False)['Mean_Range'].mean().sort_values('rcs') x_clean = clean_df['rcs'] y_clean = clean_df['Mean_Range'] # 原插值绘图逻辑 xnew = np.linspace(x_clean.min(), x_clean.max(), 200) cubic_interp_model = interp1d(x_clean, y_clean, kind="cubic") y_interp = cubic_interp_model(xnew) pl.plot(xnew, y_interp)
方案2:直接去重(适合重复值是采集/存储产生的冗余脏数据的场景)
如果重复条目是无意义的冗余数据,直接按rcs列去重,保留第一条或者最后一条记录即可:
# 按rcs去重,保留首次出现的记录后排序 clean_df = all_dat.drop_duplicates(subset='rcs', keep='first').sort_values('rcs') x_clean = clean_df['rcs'] y_clean = clean_df['Mean_Range'] # 后续插值绘图逻辑和方案1一致
方案3:更换插值类型(适合不想修改原始数据的场景)
如果不需要三次样条的平滑插值效果,可以把插值类型换成支持重复x值的线性、最近邻插值,不需要预处理数据:
# 仅需修改kind参数,其余代码不变 cubic_interp_model = interp1d(x, y, kind="linear")
注意:无论用哪种方案,最终传入
interp1d做三次插值的x序列必须满足无重复、单调递增两个要求,否则依然会触发插值相关报错。
内容的提问来源于stack exchange,提问作者Mageo
相关产品推荐
相关产品推荐

