【问题标题】:Numpy - constructing matrix of Jaro (or Levenshtein) distances using numpy.fromfunctionNumpy - 使用 numpy.fromfunction 构建 Jaro(或 Levenshtein)距离矩阵
【发布时间】:2015-04-22 18:32:02
【问题描述】:

我现在正在做一些文本分析,作为其中的一部分,我需要得到一个特定列表中所有单词之间的 Jaro 距离矩阵(所以成对距离矩阵),如下所示:

       │CHEESE CHORES GEESE  GLOVES
───────┼───────────────────────────
CHEESE │    0   0.222  0.177  0.444     
CHORES │0.222       0  0.422  0.333
GEESE  │0.177   0.422      0  0.300
GLOVES │0.444   0.333  0.300      0

所以,我尝试使用numpy.fromfunction 构建它。根据文档和示例,它将坐标传递给函数,获取结果,构造结果矩阵。

我尝试了以下方法:

from jellyfish import jaro_distance

def distance(i, j):
    return 1 - jaro_distance(feature_dict[i], feature_dict[j])

feature_dict = 'CHEESE CHORES GEESE GLOVES'.split()
distance_matrix = np.fromfunction(distance, shape=(len(feature_dict),len(feature_dict)))

注意:jaro_distance 只接受 2 个字符串并返回一个浮点数。

我得到了一个错误:

File "<pyshell#26>", line 4, in distance
    return 1 - jaro_distance(feature_dict[i], feature_dict[j])
TypeError: only integer arrays with one element can be converted to an index

我在函数的开头添加了print(i)print(j),我发现传递的不是真实坐标,而是一些奇怪的东西:

[[ 0.  0.  0.  0.]
 [ 1.  1.  1.  1.]
 [ 2.  2.  2.  2.]
 [ 3.  3.  3.  3.]]
[[ 0.  1.  2.  3.]
 [ 0.  1.  2.  3.]
 [ 0.  1.  2.  3.]
 [ 0.  1.  2.  3.]]

为什么? numpy 网站上的examples 清楚地表明只传递了两个整数,没有别的。

我尝试使用 lambda 函数完全重现他们的示例,但我得到完全相同的错误:

distance_matrix = np.fromfunction(lambda i, j: 1 - jaro_distance(feature_dict[i], feature_dict[j]), shape=(len(feature_dict),len(feature_dict)))

感谢您的帮助 - 我想我以某种方式误解了它。

【问题讨论】:

  • 你能把它变成complete example吗? feature_dict 是什么? jaro_distance()的调用签名是什么?
  • 这是一个完整的例子,我相信。功能字典是按照相关代码中提供的那样生成的:feature_dict = 'CHEESE CHORES GEESE GLOVES'.split()
  • jaro_distance 只需获取 2 个字符串并返回一个浮点数。不是我的功能,是水母提供的
  • 你可能会看这篇文章:*.com/questions/18702105/…(第一个答案)- NumPy 的fromfunction 文档有些误导
  • 感谢@xnx,它包含所需的信息。

标签: python arrays numpy matrix


【解决方案1】:

正如@xnx 所建议的,我调查了question 并发现 fromfunc 不是一个一个地传递坐标,而是实际上同时传递了所有索引。这意味着如果数组的形状为 (2,2),numpy 将不会执行f(0,0), f(0,1), f(1,0), f(1,1),而是会执行:

f([[0., 0.], [1., 1.]], [[0., 1.], [0., 1.]])

但看起来我的特定函数可以矢量化并产生所需的结果。所以实现所需的代码如下:

from jellyfish import jaro_distance
import numpy
def distance(i, j):
    return 1 - jaro_distance(feature_dict[i], feature_dict[j])

feature_dict = 'CHEESE CHORES GEESE GLOVES'.split()

funcProxy = np.vectorize(distance)

distance_matrix = np.fromfunction(funcProxy, shape=(len(feature_dict),len(feature_dict)))

而且效果很好。

【讨论】: