Sicher gibt es eine np.einsum
Art und Weise, wie so -
np.einsum('ij,ij->i',X.dot(M),X)
This missbraucht die schnelle Matrix-Multiplikation auf der ersten Ebene mit X.dot(M)
und verwendet dann np.einsum
, um die erste Achse zu halten und die Summe reduziert die zweite Achse.
Runtime Test -
In diesem Abschnitt werden alle bisher geschrieben Ansätze, das Problem zu lösen.
In [132]: # Setup input arrays
...: X = np.random.randn(10000, 100)
...: M = np.random.rand(100, 100)
...:
...: def original_app(X,M):
...: out = np.zeros(10000)
...: for n in range(10000):
...: out[n] = np.dot(np.dot(X[n, :], M), X[n, :])
...: return out
...:
In [133]: np.allclose(original_app(X,M),np.einsum('ij,ij->i',X.dot(M),X))
Out[133]: True
In [134]: %timeit original_app(X,M) # Original solution
10 loops, best of 3: 97.8 ms per loop
In [135]: %timeit np.dot(X, np.dot(M,X.T)).trace()# @Colonel Beauvel's solution
1 loops, best of 3: 2.24 s per loop
In [136]: %timeit np.einsum('ij,jk,ik->i', X, M, X) # @hpaulj's solution
1 loops, best of 3: 442 ms per loop
In [137]: %timeit np.einsum('ij,ij->i',X.dot(M),X) # Proposed in this post
10 loops, best of 3: 28.1 ms per loop
leid M = numpy.random.rand (100, 100) –
warum nicht verwenden 'np.dot (np.dot (x [n,:], M), x [n,:]). diagonal() ' – co2y
Neugierig - Hat eine der veröffentlichten Lösungen für Sie funktioniert? – Divakar