Alz*_*Alz 3 python benchmarking interpolation numpy scipy
假设我们有一个数组a = np.array([1,2,0,4,0,5,0,0,11]),我们如何得到:
array([ 1, 2, 3, 4, 4.5, 5, 7, 9, 11])\nRun Code Online (Sandbox Code Playgroud)\n\n我尝试过的是:
\n\nfrom scipy.interpolate import interp1d\n\na = np.array([1,2,0,4,0,5,0,0,11])\nb = a[np.nonzero(a)]\nbrange = np.arange(b.shape[0])\ninterp = interp1d(brange, b)\nRun Code Online (Sandbox Code Playgroud)\n\n这似乎确实完成了寻找中间值的实际工作。例如:
\n\nprint (interp(1), interp(1.5), interp(2), interp(2.5), interp(3))\n#out: 2.0 3.0 4.0 4.5 5.0\nRun Code Online (Sandbox Code Playgroud)\n\n但我不知道如何从interp. 我也尝试了这个问题的解决方案,但该解决方案也遇到了完全相同的问题。
更新:
\n\n我使用 numpy 和 pandas 对这两个解决方案进行了快速基准测试,结果如下:
\n\ny = np.array([1,2,0,4,0,5,0,0,11])\n\ndef test1(y):\n\n x = np.arange(len(y))\n idx = np.nonzero(y)\n interp = interp1d(x[idx],y[idx])\n\n return interp(x)\n\ndef test2(y):\n s = pd.Series(y)\n s.interpolate(inplace=True)\n return s.values\n\n%timeit t1 = test1(y)\n%timeit t2 = test2(y)\n\n139 \xc2\xb5s \xc2\xb1 1.62 \xc2\xb5s per loop (mean \xc2\xb1 std. dev. of 7 runs, 10000 loops each)\n158 \xc2\xb5s \xc2\xb1 2.01 \xc2\xb5s per loop (mean \xc2\xb1 std. dev. of 7 runs, 10000 loops each)\nRun Code Online (Sandbox Code Playgroud)\n\n大约快 12%。没有我希望的那么好,但是由于代码将运行数百万次,因此可能值得付出努力。
\n您需要提供一个不带interp1d零的y 数组和一个跳过所述零的 x 数组。然后,对于插值,您必须为插值函数提供一个 x 数组,其中包含所有原始 x 值以及您希望出现插值的值。在您的情况下,由于您有一个准备好的等距向量,因此您可以用来生成 x 值并过滤掉零。np.arangenp.where
这里是一个示例代码:
import numpy as np
from scipy.interpolate import interp1d
y = np.array([1,2,0,4,0,5,0,0,11])
xnew = np.arange(len(y))
zero_idx = np.where(y==0)
xold = np.delete(xnew,zero_idx)
yold = np.delete(y, zero_idx)
print('before')
print(xold)
print(yold)
f = interp1d(xold,yold)
ynew = f(xnew)
print()
print('after')
print(xnew)
print(ynew)
Run Code Online (Sandbox Code Playgroud)
结果如下:
before
[0 1 3 5 8]
[ 1 2 4 5 11]
after
[0 1 2 3 4 5 6 7 8]
[ 1. 2. 3. 4. 4.5 5. 7. 9. 11. ]
Run Code Online (Sandbox Code Playgroud)
编辑:
实际上你不需要np.delete,你可以只使用切片:
y = np.array([1,2,0,4,0,5,0,0,11])
x = np.arange(len(y))
idx = np.where(y!=0) #or np.nonzero(y) -- thanks DanielF
f = interp1d(x[idx],y[idx])
ynew = f(x)
Run Code Online (Sandbox Code Playgroud)