早些时候,我问了一个类似的question,答案使用np.dot
,利用了点积涉及一系列产品的事实。 (据我所知。)
现在我有一个类似的问题,我不认为dot
会适用,因为我想采用一个元素方式对角线代替一个总和。如果是这样,我就无法正确应用它。
给定矩阵x
和数组err
:
x = np.matrix([[ 0.02984406, -0.00257266],
[-0.00257266, 0.00320312]])
err = np.array([ 7.6363226 , 13.16548267])
我目前使用循环的实现是:
res = np.array([np.sqrt(np.diagonal(x * err[i])) for i in range(err.shape[0])])
print(res)
[[ 0.47738755 0.15639712]
[ 0.62682649 0.20535487]]
,x.dot(i)
中的每个i
的对角线为err
。这可以被矢量化吗?换句话说,x * err
的输出可以是3维的,np.diagonal
然后产生2d数组,每个对角线有一个元素吗?
答案 0 :(得分:2)
程序:
import numpy as np
x = np.matrix([[ 0.02984406, -0.00257266],
[-0.00257266, 0.00320312]])
err = np.array([ 7.6363226 , 13.16548267])
diag = np.diagonal(x)
ans = np.sqrt(diag*err[:,np.newaxis]) # sqrt of outer product
print(ans)
# use out keyword to avoid making new numpy array for many times.
ans = np.empty(x.shape, dtype=x.dtype)
for i in range(100):
ans = np.multiply(diag, err, out=ans)
ans = np.sqrt(ans, out=ans)
结果:
[[ 0.47738755 0.15639712]
[ 0.62682649 0.20535487]]
答案 1 :(得分:2)
这是一种方法,将diagonal-view
与ndarray.flat
一起用于x
,然后使用broadcasting
进行逐元素乘法,就像这样 -
np.sqrt(x.flat[::x.shape[1]+1].A1 * err[:,None])
示例运行 -
In [108]: x = np.matrix([[ 0.02984406, -0.00257266],
...: [-0.00257266, 0.00320312]])
...:
...: err = np.array([ 7.6363226 , 13.16548267])
...:
In [109]: np.sqrt(x.flat[::x.shape[1]+1].A1 * err[:,None])
Out[109]:
array([[ 0.47738755, 0.15639712],
[ 0.62682649, 0.20535487]])
运行时测试,了解view
如何帮助创建副本的np.diagonal
-
In [104]: x = np.matrix(np.random.rand(5000,5000))
In [105]: err = np.random.rand(5000)
In [106]: %timeit np.diagonal(x)*err[:,np.newaxis]
10 loops, best of 3: 66.8 ms per loop
In [107]: %timeit x.flat[::x.shape[1]+1].A1 * err[:,None]
10 loops, best of 3: 37.7 ms per loop