Suppose an array a.shape == (N, M)
and a vector v.shape == (N,)
. The goal is to compute argmin
of abs
of v
subtracted from every element of a
- that is,
out = np.zeros(N, M)
for i in range(N):
for j in range(M):
out[i, j] = np.argmin(np.abs(a[i, j] - v))
I have a vectorized implementation via np.matlib.repmat
, and it's much faster, but takes O(M*N^2)
memory, unacceptable in practice. Computation's still done on CPU so best bet seems to be implementing the for-loop in C as an extension, but maybe Numpy already has this logic implemented.
Does it? Any use-ready Numpy functions implementing above efficiently?
Matrix and Element-wise Operations Some operations are intended for matrices in particular. the conjugate and non-conjugate transpose operators 'and.', the matrix multiplication operator, and the left and right
Element-wise multiplication of two vector is one of especial hadamard products. In this tutorial, we will introduce element-wise multiplication for machine learning beginners. Element-wise multiplication is widely used in neural network, For example:
In this tutorial, we will introduce element-wise multiplication for machine learning beginners. Element-wise multiplication is widely used in neural network, For example: Where Θ is the element-wise multiplication. What is the element-wise multiplication?
Such solutions to matrix equations are solved exactly (with Gaussian elimination) if the matrix is square; others are solved in a least-squares sense (with Householder orthogonalization). Also see help slash . To get inner and outer products of vectors, remember their formal definitions.
Inspired by this post
, we can leverage np.searchsorted
-
def find_closest(a, v):
sidx = v.argsort()
v_s = v[sidx]
idx = np.searchsorted(v_s, a)
idx[idx==len(v)] = len(v)-1
idx0 = (idx-1).clip(min=0)
m = np.abs(a-v_s[idx]) >= np.abs(v_s[idx0]-a)
m[idx==0] = 0
idx[m] -= 1
out = sidx[idx]
return out
Some more perf. boost with numexpr
on large datasets :
import numexpr as ne
def find_closest_v2(a, v):
sidx = v.argsort()
v_s = v[sidx]
idx = np.searchsorted(v_s, a)
idx[idx==len(v)] = len(v)-1
idx0 = (idx-1).clip(min=0)
p1 = v_s[idx]
p2 = v_s[idx0]
m = ne.evaluate('(idx!=0) & (abs(a-p1) >= abs(p2-a))', {'p1':p1, 'p2':p2, 'idx':idx})
idx[m] -= 1
out = sidx[idx]
return out
Timings
Setup :
N,M = 500,100000
a = np.random.rand(N,M)
v = np.random.rand(N)
In [22]: %timeit find_closest_v2(a, v)
4.35 s ± 21.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
In [23]: %timeit find_closest(a, v)
4.69 s ± 173 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With