我如何使用另一个模块中的一个或一组函数作为我自己的函数中的参数我定义?
我试图编写一个比较一个向量q
的函数,并计算它与一组向量x
中每个向量的距离。函数get_distances
应采用一个向量q
,向量集x
和参数dist_method
。 dist_method
应该从scipy.spatial.distance中进行任何一个距离计算并将其用于计算,所以我可以调用这样的函数:distances = get_distances(q, x, 'euclidean')
这里是scipy参考页面 - get_distances
应该可以使用任何距离函数braycurtis,canberra,...,sqeuclidean,wminkowski:
https://docs.scipy.org/doc/scipy/reference/spatial.distance.html
在此函数所在的file1.py
文件的顶部,我已导入scipy.spatial.distance,我认为我应该可以访问函数,例如distance.euclidean( ),但是当我在翻译中调用get_distances
时,我得到AttributeError: 'module' object has no attribute 'dist_method'
。
我发现很多答案就像下面说的那样,功能是一流的对象'并且我应该能够像其他任何论点一样使用它们作为参数,并且我尝试过使用** kwargs概念,但我无法将它们全部放在一起。
有人能帮我理解我错过的东西吗?
KNN.py:
import numpy as np
import scipy.spatial.distance as dist
def get_distances(q, x, dist_method='euclidean', *args, **kwargs):
"""Query dataset to get distances for KNN
Given a numpy array of vectors x and
query point q, use dist_method to calculate
distance from q to each vector in x
Parameters:
q: tuple
x: numpy array
dist_method (optional): distance function from scipy.spatial.distance
Returns: list of distances
"""
return [dist.dist_method(q, x_i) for x_i in x]
def load_samples():
x = np.array([[1, 6],[2, 4],[3, 7],[6, 8],[7, 1],[8, 4]])
y = np.array([[7],[8],[16],[44],[50],[68]])
q = (4, 2)
return x, y, q
这是我在翻译中所做的事情:
>>> import KNN as knn
>>> x, y, q = knn.load_samples()
>>> x
array([[1, 6],
[2, 4],
[3, 7],
[6, 8],
[7, 1],
[8, 4]])
>>> d = knn.get_distances(q, x, 'cityblock')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "KNN.py", line 19, in get_distances
return [dist.dist_method(q, x_i) for x_i in x]
AttributeError: 'module' object has no attribute 'dist_method'
答案 0 :(得分:2)
问题:
return [dist.dist_method(q, x_i) for x_i in x]
是您尝试使用dist_method
来访问名称与字符串值匹配的dist
中的函数(即"euclidean"
),但是dist.dist_method
会查找"dist_method"
对象中名为dist
的函数,该函数不存在。
要按名称访问对象的函数,可以使用getattr
,它将返回与字符串匹配的对象属性。
您想要做的是:
[getattr(dist,dist_method)(q, x_i) for x_i in x]
答案 1 :(得分:0)
@TheoretiCAL的回答显示了一种获得理想结果的方法,这是另一种方法:
methods = {
'canberra': dist.canberra,
'euclidean': dist.euclidean,
# etc
}
def get_distances(q, x, dist_method=None, *args, **kwargs):
method = methods.get(dist_method, dist.euclidean)
return [method(q, x_i) for x_i in x]
答案 2 :(得分:-2)
问题是dist_method
不是您尝试使用的模块中的任何内容的名称。您可以使用模块__dict__
属性来&#34;获取&#34;适当的方法。
[dist.__dict__[dist_method](q, x_i) for x_i in x]