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

如何为Scipy的cdist(或pdist)自定义函数传递额外参数?

解决Scipy cdist自定义度量函数传递额外参数的问题

这问题我之前也踩过坑!Scipy的cdist对自定义度量函数的签名有严格要求——只能接受两个输入参数(即待比较的两个向量u和v),所以你直接带k=7传进去肯定会报错。下面给你几个比全局变量优雅得多的解决方案:

方法1:用Lambda函数做参数适配

最简单的方式就是用lambda把额外参数k绑定进去,给cdist提供它需要的双参数接口:

import numpy as np
from scipy.spatial.distance import cdist

def cust_metric(u, v, k):
    dist = np.cumsum(np.gcd(u, v) * k)
    return dist

# 调用时用lambda封装k参数
arr1 = np.array([[1,2],[3,4]])
arr2 = np.array([[5,6],[7,8]])
d_ar = cdist(arr1, arr2, metric=lambda u, v: cust_metric(u, v, k=7))

lambda在这里就像一个“适配器”,帮你把三参数的自定义函数转换成cdist能识别的双参数函数。

方法2:用functools.partial做偏函数绑定

如果觉得lambda不够直观,Python标准库的functools.partial是专门用来固定函数部分参数的工具,可读性更强:

import numpy as np
from scipy.spatial.distance import cdist
from functools import partial

def cust_metric(u, v, k):
    dist = np.cumsum(np.gcd(u, v) * k)
    return dist

# 预先绑定k参数,生成一个只需要u和v的新函数
custom_metric_with_k = partial(cust_metric, k=7)
d_ar = cdist(arr1, arr2, metric=custom_metric_with_k)

这种方式特别适合自定义函数有多个额外参数的场景,代码逻辑会更清晰。

方法3:用类封装状态(适合复杂场景)

如果你的度量逻辑以后需要扩展,比如要传递多个参数或者维护一些状态,用类的__call__方法来实现会更灵活:

import numpy as np
from scipy.spatial.distance import cdist

class CustMetric:
    def __init__(self, k):
        self.k = k  # 把k作为类的属性保存
    
    def __call__(self, u, v):
        # 调用实例时就像调用函数一样,自动传入u和v
        dist = np.cumsum(np.gcd(u, v) * self.k)
        return dist

# 实例化时传入k参数
metric_obj = CustMetric(k=7)
d_ar = cdist(arr1, arr2, metric=metric_obj)

类的方式可以很好地封装所有需要的参数,避免全局变量带来的命名污染和维护问题。

这三种方法都能完美解决你的问题,推荐根据场景选择:简单需求用lambda,参数多的时候用partial,复杂逻辑用类封装。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 17:43:09