当我将两个numpy数组(nxn)*(nx 1)相乘时,得到一个大小为(nxn)的矩阵.遵循正常的矩阵乘法规则,期望一个(nx 1)向量,但我根本无法找到有关如何在Python的Numpy模块中完成此操作的任何信息.
问题是我不想手动实现它以保持程序的速度.
示例代码如下所示:
a = np.array([[ 5, 1 ,3], [ 1, 1 ,1], [ 1, 2 ,1]])
b = np.array([1, 2, 3])
print a*b
>>
[[5 2 9]
[1 2 3]
[1 4 3]]
Run Code Online (Sandbox Code Playgroud)
我想要的是:
print a*b
>>
[16 6 8]
Run Code Online (Sandbox Code Playgroud) 我通常从numpy的einsum函数中获得了很好的表现(我喜欢它的语法).@Ophion对这个问题的回答表明 - 对于测试的案例 - einsum始终优于"内置"功能(有时候会有一些,有时会很多).但我刚遇到一个einsum慢得多的情况.考虑以下等效函数:
(M, K) = (1000000, 20)
C = np.random.rand(K, K)
X = np.random.rand(M, K)
def func_dot(C, X):
Y = X.dot(C)
return np.sum(Y * X, axis=1)
def func_einsum(C, X):
return np.einsum('ik,km,im->i', X, C, X)
def func_einsum2(C, X):
# Like func_einsum but break it into two steps.
A = np.einsum('ik,km', X, C)
return np.einsum('ik,ik->i', A, X)
Run Code Online (Sandbox Code Playgroud)
我希望func_einsum跑得最快,但这不是我遇到的.在具有超线程,numpy版本1.9.0.dev-7ae0206的四核CPU上运行,以及使用OpenBLAS进行多线程处理,我得到以下结果:
In [2]: %time y1 = func_dot(C, X)
CPU times: user 320 ms, sys: 312 ms, total: 632 …Run Code Online (Sandbox Code Playgroud) 可以说,我有一堆矩阵 As 和向量 bs 。
As = array([[[1, 7], [3, 8]],
[[2, 1], [5, 9]],
[[7, 2], [8, 3]]])
bs = array([[8, 0], [8, 8], [7, 3]])
Run Code Online (Sandbox Code Playgroud)
当我执行 np.inner(As, bs) 时,我得到:
array([[[ 8, 64, 28], [ 24, 88, 45]],
[[ 16, 24, 17], [ 40, 112, 62]],
[[ 56, 72, 55], [ 64, 88, 65]]])
Run Code Online (Sandbox Code Playgroud)
但我不需要所有的内部产品。我想要的是,用每个向量计算每个矩阵一次。我可以做这样的事情:
np.array(map(lambda (a, b): np.inner(a, b), zip(As, bs)))
Run Code Online (Sandbox Code Playgroud)
然后我得到预期的矩阵:
array([[ 8, 24], [ 24, 112], [ 55, 65]])
Run Code Online (Sandbox Code Playgroud)
现在我不想使用 zip、map 等,因为我需要此操作 > 10**6 次(对于图像处理,对于 GMM …
我需要对两个 4D 数组(m 和 n)执行矩阵乘法,m 和 n 的尺寸分别为 2x2x2x2 和 2x3x2x2,这应该会产生 2x3x2x2 数组。经过大量研究(主要在本网站上),似乎可以使用np.einsum或np.tensordot有效地完成此操作,但我无法复制从 Matlab 获得的答案(手动验证)。我了解这些方法(einsum和tensordot)在二维数组上执行矩阵乘法时如何工作(这里清楚地解释了清楚解释),但我无法获得 4D 数组的正确轴索引。显然我\xe2\x80\x99m 缺少一些东西!我的实际问题涉及两个 23x23x3x3 复数数组,但我的测试数组是:
\n\na = np.array([[1, 7], [4, 3]]) \nb = np.array([[2, 9], [4, 5]]) \nc = np.array([[3, 6], [1, 0]]) \nd = np.array([[2, 8], [1, 2]]) \ne = np.array([[0, 0], [1, 2]])\nf = np.array([[2, 8], [1, 0]])\n\nm = np.array([[a, b], [c, d]]) # (2,2,2,2)\nn = np.array([[e, f, a], [b, d, c]]) # (2,3,2,2)\nRun Code Online (Sandbox Code Playgroud)\n\n我意识到复数可能会带来更多问题,但现在,我只是想了解索引如何与 …
对于二维矩阵X( shape (m,n)),我试图计算矩阵乘法 X.T * X在哪里。按照这篇文章的解释,我希望能够使用以下方法来做到这一点:在 LHS 上,首先对第一个参数进行转置,然后将其乘以第二个参数。*np.einsum('ji,ik->jk', X, X)jiXX
这不适用于错误(对于(m,n) = (3,4)):
ValueError: operands could not be broadcast together with remapped shapes [original->remapped]: (4,3)->(4,newaxis,3) (4,3)->(3,4)
然而,这有效:np.einsum('ij,jk->ik', X.T, X). 我在这里缺少什么?为什么它还要在中间添加一个轴?
我有两个数组,第一个 np.array 是来自的点,第二个 np.array 是我需要计算的所有距离。
例子:
import numpy as np
from_array = np.array([(0,1), (1,1), ..., (x,y)])
to_array = np.array([(5,1), (3,1), ..., (x,y)])
Run Code Online (Sandbox Code Playgroud)
我需要做的是取第一个条目from_array并计算from_array[0]到to_array中所有点之间的所有距离,然后保持最大距离。
所以我可以为此蛮力:
def get_distances(from_array, to_array):
results = []
distances = []
for pt in from_array:
for to in to_array:
results.append(calc_dist(pt, to))
distances.append(results)
return distances
Run Code Online (Sandbox Code Playgroud)
但这很慢,我正在寻找一种优化的计算方式,因为我可以有数千个点。
最终目标是计算 Hausdorff 距离。
fhd = np.mean(np.min(SomeDistanceArray,axis=0))
rhd = np.mean(np.min(SomeDistanceArray,axis=1))
print (max(fhd, rhd))
Run Code Online (Sandbox Code Playgroud)
我想用numpy的这个任务只。我的距离可以是欧氏距离或平方欧氏距离。
所以我正在寻找帮助是计算两个 np.arrays 的欧几里德距离方法的优化方法。应该注意的是,数组 1 的行数可能比数组 2 多。这意味着二维数组的长度 (x,y) 可以将 10 行与 30 行进行比较。
假设我有一个像这样的 numpy 矩阵:
[[ 1 2 3]
[ 10 100 1000]]
Run Code Online (Sandbox Code Playgroud)
我想用它自己计算每列的内积,所以结果是:
[1*1 + 10*10 2*2 + 100*100 3*3 + 1000*1000] == [101, 10004, 1000009]
Run Code Online (Sandbox Code Playgroud)
我想知道这是否可以使用该einsum函数(并更好地理解它)。
到目前为止,我能得到的最接近的结果是:
import numpy as np
arr = np.array([[1, 2, 3], [10, 100, 1000]])
res = np.einsum('ij,ik->jk', arr, arr)
# [[ 101 1002 10003]
# [ 1002 10004 100006]
# [ 10003 100006 1000009]]
Run Code Online (Sandbox Code Playgroud)
对角线包含预期结果,但我想知道是否可以避免边缘计算。
刚遇到这个:
这个 numpy.einsum 真的很棒,但使用起来有点混乱。假设我有:
import numpy as np
a = np.array([[1,2,3], [3,4,5]])
b = np.array([[0,1,2], [1,1,7]])
Run Code Online (Sandbox Code Playgroud)
我将如何使用 einsum 中的“ij”来获得 a 和 b 之间的“交叉点积”?
使用这个例子基本上我想计算的点积
[1,2,3] 和 [0,1,2]
[1,2,3] 和 [1,2,7]
[3,4,5] 和 [0,1,2]
[3,4,5] 和 [1,1,7]
并以 [[8,26],[14,42]] 结束
我知道如果我使用
np.einsum("ij,ij->i",a,b)
Run Code Online (Sandbox Code Playgroud)
我最终会得到 [8, 42] 这意味着我缺少“交叉”元素
numpy ×8
python ×8
matrix ×6
arrays ×2
performance ×2
vector ×2
dot-product ×1
numpy-einsum ×1