在二维数组上使用numpy.interp的最快方法

时间:2017-05-04 01:02:35

标签: numpy interpolation linear-interpolation

我有以下问题。我试图找到在x坐标的二维数组上使用numpy插值方法的最快方法。

import numpy as np

xp = [0.0, 0.25, 0.5, 0.75, 1.0]

np.random.seed(100)
x = np.random.rand(10)
fp = np.random.rand(10, 5)

基本上,xp将是数据点的x坐标,x将是一个包含我想要插值的x坐标的数组,fp将是一个包含数据点的y坐标的二维数组。

xp
[0.0, 0.25, 0.5, 0.75, 1.0]

x
array([ 0.54340494,  0.27836939,  0.42451759,  0.84477613,  0.00471886,
        0.12156912,  0.67074908,  0.82585276,  0.13670659,  0.57509333])

fp
array([[ 0.89132195,  0.20920212,  0.18532822,  0.10837689,  0.21969749],
       [ 0.97862378,  0.81168315,  0.17194101,  0.81622475,  0.27407375],
       [ 0.43170418,  0.94002982,  0.81764938,  0.33611195,  0.17541045],
       [ 0.37283205,  0.00568851,  0.25242635,  0.79566251,  0.01525497],
       [ 0.59884338,  0.60380454,  0.10514769,  0.38194344,  0.03647606],
       [ 0.89041156,  0.98092086,  0.05994199,  0.89054594,  0.5769015 ],
       [ 0.74247969,  0.63018394,  0.58184219,  0.02043913,  0.21002658],
       [ 0.54468488,  0.76911517,  0.25069523,  0.28589569,  0.85239509],
       [ 0.97500649,  0.88485329,  0.35950784,  0.59885895,  0.35479561],
       [ 0.34019022,  0.17808099,  0.23769421,  0.04486228,  0.50543143]])

期望的结果应如下所示:

array([ 0.17196795,  0.73908678,  0.85459966,  0.49980648,  0.59893702,
        0.9344241 ,  0.19840596,  0.45777785,  0.92570835,  0.17977264])

同样,寻找最快的方法导致这是我的问题的简化版本,其长度约为100万而不是10。

由于

2 个答案:

答案 0 :(得分:6)

所以基本上你想要输出相当于

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.shape.*?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<AnchorPane id="AnchorPane" prefHeight="615.0" prefWidth="1070.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="taxerfxml.FXMLDocumentController">
    <children>
      <Accordion layoutX="14.0" layoutY="14.0" />
      <Label layoutX="238.0" layoutY="6.0" text="Sale" />
      <Label layoutX="358.0" layoutY="6.0" text="Tax" />
      <Label layoutX="491.0" layoutY="6.0" text="County" />
      <Label layoutX="622.0" layoutY="6.0" text="Freight" />
      <Label layoutX="741.0" layoutY="6.0" text="Labor" />
      <Label layoutX="857.0" layoutY="6.0" text="Cost" />
      <Label layoutX="994.0" layoutY="6.0" text="Profit" />
      <Label layoutX="14.0" layoutY="6.0" text="Customer" />
      <TextField layoutY="81.0" text="Customer 1" />
      <TextField layoutY="125.0" text="Customer 2" />
      <TextField layoutY="168.0" text="Customer 3" />
      <TextField layoutY="212.0" text="Customer 4" />
      <TextField layoutY="256.0" text="Customer 5" />
      <TextField layoutY="303.0" text="Customer 6" />
      <TextField layoutY="346.0" text="Customer 7" />
      <TextField layoutY="394.0" text="Customer 8" />
      <TextField layoutY="439.0" text="Customer 9" />
      <TextField layoutY="485.0" text="Customer 10" />
      <TextField layoutY="537.0" text="Customer 11" />
      <TextField layoutY="582.0" text="Customer 12" />
      <TextField layoutX="205.0" layoutY="83.0" prefHeight="25.0" prefWidth="88.0" text="Sale1" />
      <TextField layoutX="205.0" layoutY="127.0" prefHeight="25.0" prefWidth="88.0" text="Sale2" />
      <TextField layoutX="205.0" layoutY="170.0" prefHeight="25.0" prefWidth="88.0" text="Sale3" />
      <TextField layoutX="205.0" layoutY="214.0" prefHeight="25.0" prefWidth="88.0" text="Sale4" />
      <TextField layoutX="205.0" layoutY="258.0" prefHeight="25.0" prefWidth="88.0" text="Sale5" />
      <TextField layoutX="205.0" layoutY="305.0" prefHeight="25.0" prefWidth="88.0" text="Sale6" />
      <TextField layoutX="205.0" layoutY="348.0" prefHeight="25.0" prefWidth="88.0" text="Sale7" />
      <TextField layoutX="205.0" layoutY="396.0" prefHeight="25.0" prefWidth="88.0" text="Sale8" />
      <TextField layoutX="205.0" layoutY="441.0" prefHeight="25.0" prefWidth="88.0" text="Sale9" />
      <TextField layoutX="205.0" layoutY="487.0" prefHeight="25.0" prefWidth="88.0" text="Sale10" />
      <TextField layoutX="205.0" layoutY="539.0" prefHeight="25.0" prefWidth="88.0" text="Sale11" />
      <TextField layoutX="205.0" layoutY="584.0" prefHeight="25.0" prefWidth="88.0" text="Sale12" />
      <TextField layoutX="319.0" layoutY="83.0" prefHeight="25.0" prefWidth="97.0" text="Tax1" />
      <TextField layoutX="319.0" layoutY="127.0" prefHeight="25.0" prefWidth="97.0" text="Tax2" />
      <TextField layoutX="319.0" layoutY="168.0" prefHeight="25.0" prefWidth="97.0" text="Tax3" />
      <TextField layoutX="319.0" layoutY="214.0" prefHeight="25.0" prefWidth="97.0" text="Tax4" />
      <TextField layoutX="319.0" layoutY="258.0" prefHeight="25.0" prefWidth="97.0" text="Tax5" />
      <TextField layoutX="319.0" layoutY="305.0" prefHeight="25.0" prefWidth="97.0" text="Tax6" />
      <TextField layoutX="319.0" layoutY="348.0" prefHeight="25.0" prefWidth="97.0" text="Tax7" />
      <TextField layoutX="319.0" layoutY="394.0" prefHeight="25.0" prefWidth="97.0" text="Tax8" />
      <TextField layoutX="319.0" layoutY="441.0" prefHeight="25.0" prefWidth="97.0" text="Tax9" />
      <TextField layoutX="319.0" layoutY="487.0" prefHeight="25.0" prefWidth="97.0" text="Tax10" />
      <TextField layoutX="319.0" layoutY="539.0" prefHeight="25.0" prefWidth="97.0" text="Tax11" />
      <TextField layoutX="319.0" layoutY="584.0" prefHeight="25.0" prefWidth="97.0" text="Tax12" />
      <ComboBox id="comboBox1" fx:id="comboBox1" layoutX="466.0" layoutY="77.0" prefHeight="34.0" prefWidth="88.0" promptText="Choose" />
      <ComboBox id="comboBox2" fx:id="comboBox2" layoutX="466.0" layoutY="120.0" prefHeight="34.0" prefWidth="88.0" promptText="Choose" /> 
      <ComboBox id="comboBox3" fx:id="comboBox3" layoutX="466.0" layoutY="166.0" prefHeight="34.0" prefWidth="88.0" promptText="Choose" />
      <ComboBox id="comboBox4" fx:id="comboBox4" layoutX="466.0" layoutY="210.0" prefHeight="34.0" prefWidth="88.0" promptText="Choose" />
      <ComboBox id="comboBox5" fx:id="comboBox5" layoutX="466.0" layoutY="254.0" prefHeight="34.0" prefWidth="88.0" promptText="Choose" />
      <ComboBox id="comboBox6" fx:id="comboBox6" layoutX="466.0" layoutY="301.0" prefHeight="34.0" prefWidth="88.0" promptText="Choose" />
      <ComboBox id="comboBox7" fx:id="comboBox7" layoutX="466.0" layoutY="344.0" prefHeight="34.0" prefWidth="88.0" promptText="Choose" />
      <ComboBox id="comboBox8" fx:id="comboBox8" layoutX="466.0" layoutY="392.0" prefHeight="34.0" prefWidth="88.0" promptText="Choose" />
      <ComboBox id="comboBox9" fx:id="comboBox9" layoutX="466.0" layoutY="437.0" prefHeight="34.0" prefWidth="88.0" promptText="Choose" />
      <ComboBox id="comboBox10" fx:id="comboBox10" layoutX="466.0" layoutY="483.0" prefHeight="34.0" prefWidth="88.0" promptText="Choose" />
      <ComboBox id="comboBox11" fx:id="comboBox11" layoutX="466.0" layoutY="533.0" prefHeight="34.0" prefWidth="88.0" promptText="Choose" />
      <ComboBox id="comboBox12" fx:id="comboBox12" layoutX="466.0" layoutY="580.0" prefHeight="34.0" prefWidth="88.0" promptText="Choose" />
      <Button fx:id="calculate" layoutX="976.0" layoutY="23.0" mnemonicParsing="false" onAction="#calculateTotal" text="Calculate" />
      <TextField layoutX="597.0" layoutY="81.0" prefHeight="17.0" prefWidth="88.0" text="Freight1" />
      <TextField layoutX="597.0" layoutY="125.0" prefHeight="17.0" prefWidth="88.0" text="Freight2" />
      <TextField layoutX="597.0" layoutY="171.0" prefHeight="17.0" prefWidth="88.0" text="Freight3" />
      <TextField layoutX="597.0" layoutY="212.0" prefHeight="17.0" prefWidth="88.0" text="Freight4" />
      <TextField layoutX="597.0" layoutY="256.0" prefHeight="17.0" prefWidth="88.0" text="Freight5" />
      <TextField layoutX="597.0" layoutY="303.0" prefHeight="17.0" prefWidth="88.0" text="Freight6" />
      <TextField layoutX="597.0" layoutY="346.0" prefHeight="17.0" prefWidth="88.0" text="Freight7" />
      <TextField layoutX="597.0" layoutY="396.0" prefHeight="17.0" prefWidth="88.0" text="Freight8" />
      <TextField layoutX="597.0" layoutY="439.0" prefHeight="17.0" prefWidth="88.0" text="Freight9" />
      <TextField layoutX="597.0" layoutY="485.0" prefHeight="17.0" prefWidth="88.0" text="Freight10" />
      <TextField layoutX="597.0" layoutY="537.0" prefHeight="17.0" prefWidth="88.0" text="Freight11" />
      <TextField layoutX="597.0" layoutY="582.0" prefHeight="17.0" prefWidth="88.0" text="Freight12" />
      <TextField layoutX="712.0" layoutY="81.0" prefHeight="25.0" prefWidth="88.0" text="Labor1" />
      <TextField layoutX="712.0" layoutY="125.0" prefHeight="25.0" prefWidth="88.0" text="Labor2" />
      <TextField layoutX="712.0" layoutY="171.0" prefHeight="25.0" prefWidth="88.0" text="Labor3" />
      <TextField layoutX="713.0" layoutY="212.0" prefHeight="25.0" prefWidth="88.0" text="Labor4" />
      <TextField layoutX="713.0" layoutY="256.0" prefHeight="25.0" prefWidth="88.0" text="Labor5" />
      <TextField layoutX="713.0" layoutY="303.0" prefHeight="25.0" prefWidth="88.0" text="Labor6" />
      <TextField layoutX="713.0" layoutY="346.0" prefHeight="25.0" prefWidth="88.0" text="Labor7" />
      <TextField layoutX="713.0" layoutY="397.0" prefHeight="25.0" prefWidth="88.0" text="Labor8" />
      <TextField layoutX="713.0" layoutY="439.0" prefHeight="25.0" prefWidth="88.0" text="Labor9" />
      <TextField layoutX="713.0" layoutY="485.0" prefHeight="25.0" prefWidth="88.0" text="Labor10" />
      <TextField layoutX="713.0" layoutY="537.0" prefHeight="25.0" prefWidth="88.0" text="Labor11" />
      <TextField layoutX="713.0" layoutY="582.0" prefHeight="25.0" prefWidth="88.0" text="Labor12" />
      <TextField layoutX="825.0" layoutY="82.0" prefHeight="25.0" prefWidth="88.0" text="Cost1" />
      <TextField layoutX="825.0" layoutY="125.0" prefHeight="25.0" prefWidth="88.0" text="Cost2" />
      <TextField layoutX="825.0" layoutY="170.0" prefHeight="25.0" prefWidth="88.0" text="Cost3" />
      <TextField layoutX="825.0" layoutY="212.0" prefHeight="25.0" prefWidth="88.0" text="Cost4" />
      <TextField layoutX="825.0" layoutY="256.0" prefHeight="25.0" prefWidth="88.0" text="Cost5" />
      <TextField layoutX="825.0" layoutY="303.0" prefHeight="25.0" prefWidth="88.0" text="Cost6" />
      <TextField layoutX="825.0" layoutY="346.0" prefHeight="25.0" prefWidth="88.0" text="Cost7" />
      <TextField layoutX="825.0" layoutY="396.0" prefHeight="25.0" prefWidth="88.0" text="Cost8" />
      <TextField layoutX="825.0" layoutY="439.0" prefHeight="25.0" prefWidth="88.0" text="Cost9" />
      <TextField layoutX="825.0" layoutY="485.0" prefHeight="25.0" prefWidth="88.0" text="Cost10" />
      <TextField layoutX="825.0" layoutY="537.0" prefHeight="25.0" prefWidth="88.0" text="Cost11" />
      <TextField layoutX="825.0" layoutY="582.0" prefHeight="25.0" prefWidth="88.0" text="Cost12" />
      <TextField layoutX="952.0" layoutY="81.0" prefHeight="25.0" prefWidth="114.0" text="Profit1" />
      <TextField layoutX="952.0" layoutY="125.0" prefHeight="25.0" prefWidth="114.0" text="Profit2" />
      <TextField layoutX="952.0" layoutY="168.0" prefHeight="25.0" prefWidth="114.0" text="Profit3" />
      <TextField layoutX="952.0" layoutY="212.0" prefHeight="25.0" prefWidth="114.0" text="Profit4" />
      <TextField layoutX="952.0" layoutY="256.0" prefHeight="25.0" prefWidth="114.0" text="Profit5" />
      <TextField layoutX="952.0" layoutY="303.0" prefHeight="25.0" prefWidth="114.0" text="Profit6" />
      <TextField layoutX="952.0" layoutY="346.0" prefHeight="25.0" prefWidth="114.0" text="Profit7" />
      <TextField layoutX="952.0" layoutY="394.0" prefHeight="25.0" prefWidth="114.0" text="Profit8" />
      <TextField layoutX="952.0" layoutY="439.0" prefHeight="25.0" prefWidth="114.0" text="Profit9" />
      <TextField layoutX="952.0" layoutY="485.0" prefHeight="25.0" prefWidth="114.0" text="Profit10" />
      <TextField layoutX="952.0" layoutY="537.0" prefHeight="25.0" prefWidth="114.0" text="Profit11" />
      <TextField layoutX="952.0" layoutY="582.0" prefHeight="25.0" prefWidth="114.0" text="Profit12" />

    </children>
</AnchorPane>

np.array([np.interp(x[i], xp, fp[i]) for i in range(x.size)]) 循环会使大for

的速度变慢

这应该有效:

x.size

编辑:这样做效果更好,可以处理更大的数组:

def multiInterp(x, xp, fp):
    i, j = np.nonzero(np.diff(np.array(xp)[None,:] < x[:,None]))
    d = (x - xp[j]) / np.diff(xp)[j]
    return fp[i, j] + np.diff(fp)[i, j] * d

测试:

def multiInterp2(x, xp, fp):
    i = np.arange(x.size)
    j = np.searchsorted(xp, x) - 1
    d = (x - xp[j]) / (xp[j + 1] - xp[j])
    return (1 - d) * fp[i, j] + fp[i, j + 1] * d

使用原始数据进行时间测试:

multiInterp2(x, xp, fp)
Out: 
array([ 0.17196795,  0.73908678,  0.85459966,  0.49980648,  0.59893702,
        0.9344241 ,  0.19840596,  0.45777785,  0.92570835,  0.17977264])

即使是小 %timeit multiInterp2(x, xp, fp) The slowest run took 6.87 times longer than the fastest. This could mean that an intermediate result is being cached. 10000 loops, best of 3: 25.5 µs per loop %timeit np.concatenate([compiled_interp(x[[i]], xp, fp[i]) for i in range(fp.shape[0])]) The slowest run took 4.03 times longer than the fastest. This could mean that an intermediate result is being cached. 10000 loops, best of 3: 39.3 µs per loop

,似乎也会更快

让我们尝试更多更大的东西:

x

n = 10000 m = 10000 xp = np.linspace(0, 1, n) x = np.random.rand(m) fp = np.random.rand(m, n) %timeit b() # kazemakase's above 10 loops, best of 3: 38.4 ms per loop %timeit multiInterp2(x, xp, fp) 100 loops, best of 3: 2.4 ms per loop

的合规版本相比,优势扩展得更好

答案 1 :(得分:2)

np.interp基本上是编译后的numpy.core.multiarray.interp的包装器。我们可以直接使用它来削减一些性能:

from numpy.core.multiarray import interp as compiled_interp

def a(x=x, xp=xp, fp=fp):
    return np.array([np.interp(x[i], xp, fp[i]) for i in range(fp.shape[0])])

def b(x=x, xp=xp, fp=fp):
    return np.concatenate([compiled_interp(x[[i]], xp, fp[i]) for i in range(fp.shape[0])])

def multiInterp(x=x, xp=xp, fp=fp):
    i, j = np.nonzero(np.diff(xp[None,:] < x[:,None]))
    d = (x - xp[j]) / np.diff(xp)[j]
    return fp[i, j] + np.diff(fp)[i, j] * d

时序测试显示,对于示例数组,这与Daniel Forsman的不错解决方案相同:

%timeit a()
10000 loops, best of 3: 44.7 µs per loop

%timeit b()
10000 loops, best of 3: 32 µs per loop

%timeit multiInterp()
10000 loops, best of 3: 33.3 µs per loop

更新

对于稍大一些的数组,multiInterp拥有底线:

n = 100
m = 1000

xp = np.linspace(0, 1, n)
x = np.random.rand(m)
fp = np.random.rand(m, n)

%timeit a()
100 loops, best of 3: 4.14 ms per loop

%timeit b()
100 loops, best of 3: 2.97 ms per loop

%timeit multiInterp()
1000 loops, best of 3: 1.42 ms per loop

但是对于更大的那些它落后了:

n = 1000
m = 10000

%timeit a()
10 loops, best of 3: 43.3 ms per loop

%timeit b()
10 loops, best of 3: 32.9 ms per loop

%timeit multiInterp()
10 loops, best of 3: 132 ms per loop

最后,对于非常大的数组(我是32位)临时数组成为一个问题:

n = 10000
m = 10000

%timeit a()
10 loops, best of 3: 46.2 ms per loop

%timeit b()
10 loops, best of 3: 32.1 ms per loop

%timeit multiInterp()
# MemoryError