Vectorization of variant of piecewise or interpolation function
Hi everybody, I am new to newpy and am trying to define a variant of piecewise or zero holder interpolation function, say ZeroOrderInterpolation(t,a), where t is an 1D array of size, say p, consisting of real numbers, and a is a 2D array of size, say nxm, with first column consisting of increasing real numbers. This function should return an array, say y, of size px(m-1) such that y[i,:] is equal to a[n,1:] if a[n,0] <= t[i], and a[k,1:] if k < n and a[k,0] <= t[i] < a[k+1,0]. Note that t[0] is assumed to be at least equal to a[0,0]. I have the following script made of "for loops" and I am trying to vectorize it so as to make it faster for large arrays. def ZeroOrderInterpolation(t,a): import numpy as np p = t.shape[0] n, m = a.shape if n == 1: return a[0,1:] y = np.zeros((p,m-1)) for i in range(p): if a[n-1,0] <= t[i]: y[i] = a[n-1,1:] else: for j in range(n-1): if (a[j,0] <= t[i]) and (t[i] <= a[j+1,0]): y[i] = a[j,1:] return y import numpy as np t = np.array([0.5,1,1.5,2.5,3,10]) table = np.array([[0,3],[1,0],[2,5],[3,-1]]) ZeroOrderInterpolation(t,table) [Out]: array([[ 3.], [ 0.], [ 0.], [ 5.], [-1.], [-1.]]) Any help for a vectorization "à la numpy" of this fucntion will be apprecaited. Best regards,
Hi Seth,
The function you’re looking for is `np.digitize`:
In [1]: t = np.array([0.5,1,1.5,2.5,3,10])
...: table = np.array([[0,3],[1,0],[2,5],[3,-1]])
...:
In [2]: lookup, values = table[:, 0], table[:, 1:]
In [3]: values = np.concatenate((values[0:1], values), axis=0)
In [4]: indices = np.digitize(t, lookup)
In [5]: values[indices]
Out[5]:
array([[ 3],
[ 0],
[ 0],
[ 5],
[-1],
[-1]])
Note the call to concatenate. Depending on how exactly you want your bins to align, you might need to concatenate at the end or at the start of the `values` array.
Hope this helps!
Juan.
On 16 Oct 2017, 1:17 PM +1100, Seth Ghandi
Hi everybody,
I am new to newpy and am trying to define a variant of piecewise or zero holder interpolation function, say ZeroOrderInterpolation(t,a), where t is an 1D array of size, say p, consisting of real numbers, and a is a 2D array of size, say nxm, with first column consisting of increasing real numbers. This function should return an array, say y, of size px(m-1) such that y[i,:] is equal to a[n,1:] if a[n,0] <= t[i], and a[k,1:] if k < n and a[k,0] <= t[i] < a[k+1,0]. Note that t[0] is assumed to be at least equal to a[0,0].
I have the following script made of "for loops" and I am trying to vectorize it so as to make it faster for large arrays.
def ZeroOrderInterpolation(t,a): import numpy as np p = t.shape[0] n, m = a.shape if n == 1: return a[0,1:] y = np.zeros((p,m-1)) for i in range(p): if a[n-1,0] <= t[i]: y[i] = a[n-1,1:] else: for j in range(n-1): if (a[j,0] <= t[i]) and (t[i] <= a[j+1,0]): y[i] = a[j,1:] return y
import numpy as np t = np.array([0.5,1,1.5,2.5,3,10]) table = np.array([[0,3],[1,0],[2,5],[3,-1]]) ZeroOrderInterpolation(t,table)
[Out]: array([[ 3.], [ 0.], [ 0.], [ 5.], [-1.], [-1.]])
Any help for a vectorization "à la numpy" of this fucntion will be apprecaited.
Best regards, _______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@python.org https://mail.python.org/mailman/listinfo/numpy-discussion
Thanks so much Juan! I did not know about this np.digitize command. With this the vectorization of my function then reads as def ZeroOrderInterpolation(t,table): import numpy as np lookup, values = table[:, 0], table[:, 1:] values = np.concatenate((values[0:1], values), axis=0) indices = np.digitize(t, lookup) return values[indices] Hugs! Seth
On Oct 16, 2017, at 4:29 AM, Juan Nunez-Iglesias
wrote: Hi Seth,
The function you’re looking for is `np.digitize`:
In [1]: t = np.array([0.5,1,1.5,2.5,3,10]) ...: table = np.array([[0,3],[1,0],[2,5],[3,-1]]) ...: In [2]: lookup, values = table[:, 0], table[:, 1:] In [3]: values = np.concatenate((values[0:1], values), axis=0) In [4]: indices = np.digitize(t, lookup) In [5]: values[indices] Out[5]: array([[ 3], [ 0], [ 0], [ 5], [-1], [-1]])
Note the call to concatenate. Depending on how exactly you want your bins to align, you might need to concatenate at the end or at the start of the `values` array.
Hope this helps!
Juan.
On 16 Oct 2017, 1:17 PM +1100, Seth Ghandi
, wrote: Hi everybody,
I am new to newpy and am trying to define a variant of piecewise or zero holder interpolation function, say ZeroOrderInterpolation(t,a), where t is an 1D array of size, say p, consisting of real numbers, and a is a 2D array of size, say nxm, with first column consisting of increasing real numbers. This function should return an array, say y, of size px(m-1) such that y[i,:] is equal to a[n,1:] if a[n,0] <= t[i], and a[k,1:] if k < n and a[k,0] <= t[i] < a[k+1,0]. Note that t[0] is assumed to be at least equal to a[0,0].
I have the following script made of "for loops" and I am trying to vectorize it so as to make it faster for large arrays.
def ZeroOrderInterpolation(t,a): import numpy as np p = t.shape[0] n, m = a.shape if n == 1: return a[0,1:] y = np.zeros((p,m-1)) for i in range(p): if a[n-1,0] <= t[i]: y[i] = a[n-1,1:] else: for j in range(n-1): if (a[j,0] <= t[i]) and (t[i] <= a[j+1,0]): y[i] = a[j,1:] return y
import numpy as np t = np.array([0.5,1,1.5,2.5,3,10]) table = np.array([[0,3],[1,0],[2,5],[3,-1]]) ZeroOrderInterpolation(t,table)
[Out]: array([[ 3.], [ 0.], [ 0.], [ 5.], [-1.], [-1.]])
Any help for a vectorization "à la numpy" of this fucntion will be apprecaited.
Best regards, _______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@python.org https://mail.python.org/mailman/listinfo/numpy-discussion
NumPy-Discussion mailing list NumPy-Discussion@python.org https://mail.python.org/mailman/listinfo/numpy-discussion
participants (2)
-
Juan Nunez-Iglesias
-
Seth Ghandi