numpy中任意函数的按行广播
Row-wise Broadcast of arbitrary function in numpy
我有一个向量矩阵,其中每一行都是一个向量。我想取所有向量的平均值,然后计算每个向量与这个平均值之间的余弦距离,返回一个距离数组。
>>> x = arange(1,10).reshape(3,3)
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
>>> m = x.mean(0)
array([4., 5., 6.])
余弦值如下
>>> from scipy.spatial.distance import cosine
cosine([1,2,3], [4,5,6])
0.0253681538029239
>>> cosine([4,5,6], [4,5,6])
0.0
>>> cosine([7,8,9], [4,5,6])
0.001809107314273195
因此我想写一个函数 f
这样
>>> f(x, m)
array([0.0253681538029239, 0.0, 0.001809107314273195])
(或者这样一个数组的转置。没关系。)
什么是最有效、最 numpythonic 的编写方式f
?似乎诀窍是通过 cosine
函数进行正确的广播,但我还没有想出如何做到这一点。以下无效。
>>> from numpy import frompyfunc
>>> f = frompyfunc(cosine, 2, 1)
>>> f(x, m)
array([[0.0, 0.0, 0.0],
[0.0, 0.0, 0.0],
[0.0, 0.0, 0.0]], dtype=object)
(看起来这里 numpy 正在按元素应用 cosine
而不是按行应用。)
有没有不用写 for
循环就可以做到这一点的方法?
看起来 apply_along_axis
是可行的。
>>> from numpy import apply_along_axis
>>> from functools import partial
>>> g = partial(cosine, m)
>>> apply_along_axis(g, 1, x)
array([0.02536815, 0. , 0.00180911])
这是最有效的方法吗?
猜猜 技巧 是使用 cdist
以矢量化方式在二维数组上工作以获得那些余弦距离。所以,一种方法是 -
In [59]: from scipy.spatial.distance import cosine
In [61]: cdist(x,x.mean(0,keepdims=True),'cosine')
Out[61]:
array([[2.53681538e-02],
[2.22044605e-16],
[1.80910731e-03]])
keepdims
使输入成为 2D
,从而使其与 cdist 输入要求兼容。
您需要将均值数组重塑为二维数组。
>>> from scipy.spatial.distance import cdist
>>> cdist(x, m.reshape(1, -1), metric='cosine')
array([[2.53681538e-02],
[2.22044605e-16],
[1.80910731e-03]])
我有一个向量矩阵,其中每一行都是一个向量。我想取所有向量的平均值,然后计算每个向量与这个平均值之间的余弦距离,返回一个距离数组。
>>> x = arange(1,10).reshape(3,3)
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
>>> m = x.mean(0)
array([4., 5., 6.])
余弦值如下
>>> from scipy.spatial.distance import cosine
cosine([1,2,3], [4,5,6])
0.0253681538029239
>>> cosine([4,5,6], [4,5,6])
0.0
>>> cosine([7,8,9], [4,5,6])
0.001809107314273195
因此我想写一个函数 f
这样
>>> f(x, m)
array([0.0253681538029239, 0.0, 0.001809107314273195])
(或者这样一个数组的转置。没关系。)
什么是最有效、最 numpythonic 的编写方式f
?似乎诀窍是通过 cosine
函数进行正确的广播,但我还没有想出如何做到这一点。以下无效。
>>> from numpy import frompyfunc
>>> f = frompyfunc(cosine, 2, 1)
>>> f(x, m)
array([[0.0, 0.0, 0.0],
[0.0, 0.0, 0.0],
[0.0, 0.0, 0.0]], dtype=object)
(看起来这里 numpy 正在按元素应用 cosine
而不是按行应用。)
有没有不用写 for
循环就可以做到这一点的方法?
看起来 apply_along_axis
是可行的。
>>> from numpy import apply_along_axis
>>> from functools import partial
>>> g = partial(cosine, m)
>>> apply_along_axis(g, 1, x)
array([0.02536815, 0. , 0.00180911])
这是最有效的方法吗?
猜猜 技巧 是使用 cdist
以矢量化方式在二维数组上工作以获得那些余弦距离。所以,一种方法是 -
In [59]: from scipy.spatial.distance import cosine
In [61]: cdist(x,x.mean(0,keepdims=True),'cosine')
Out[61]:
array([[2.53681538e-02],
[2.22044605e-16],
[1.80910731e-03]])
keepdims
使输入成为 2D
,从而使其与 cdist 输入要求兼容。
您需要将均值数组重塑为二维数组。
>>> from scipy.spatial.distance import cdist
>>> cdist(x, m.reshape(1, -1), metric='cosine')
array([[2.53681538e-02],
[2.22044605e-16],
[1.80910731e-03]])