Pandas:通过在现有列之间进行线性插值来创建新列

8on*_*ne6 5 python pandas

假设我有一个 DataFrame,其中包含有关山上不同高度的温度数据,每个数据每天同时采样一次。每个探头的高度是固定的(即它们每天都保持不变)并且是已知的。每行代表一个不同的时间戳,我有一个单独的列来记录每个探头观察到的温度。我还有一列 ( targ_alt),其中每行都包含一个“感兴趣的海拔高度”。

我的目标是添加一个名为的新列intreped_temp,其中包含每一行的温度,targ_alt通过在已知高度的探头温度之间进行线性插值,您将获得该行的温度。做这个的最好方式是什么?

这是一些设置代码,因此我们可以查看相同的上下文:

import pandas as pd
import numpy as np

np.random.seed(1)

n = 10
probe_alts = {'base': 1000, 'mid': 2000, 'peak': 3500}
# let's make the temperatures decrease at higher altitudes...just for style
temp_readings = {k: np.random.randn(n) + 15 - v/300 for k, v in probe_alts.items()}
df = pd.DataFrame(temp_readings)

targ_alt = 2000 + (500 * np.random.randn(n))
df['targ_alt'] = targ_alt
Run Code Online (Sandbox Code Playgroud)

所以df看起来像这样:

        base        mid      peak     targ_alt
0  13.624345  10.462108  2.899381  1654.169624
1  11.388244   6.939859  5.144724  1801.623237
2  11.471828   8.677583  4.901591  1656.413650
3  10.927031   8.615946  4.502494  1577.397179
4  12.865408  10.133769  4.900856  1664.376935
5   9.698461   7.900109  3.316272  1993.667701
6  13.744812   8.827572  3.877110  1441.344826
7  11.238793   8.122142  3.064231  2117.207849
8  12.319039   9.042214  3.732112  2829.901089
9  11.750630   9.582815  4.530355  2371.022080
Run Code Online (Sandbox Code Playgroud)

8on*_*ne6 4

在上面给出的示例中,我想在每行中插入不同的 x 坐标。美好的。如果您不这样做...如果您想在每行中插入相同的 x 坐标,那么使用 SciPy 可以节省令人难以置信的时间。请参阅下面的示例:

\n\n
import numpy as np\nimport pandas as pd\nfrom scipy.interpolate import interp1d\n\nnp.random.seed(1)\nn = 10e4\n\ndf = pd.DataFrame({'a': np.random.randn(n), \n                   'b': 10 + np.random.randn(n), \n                   'c': 30 + np.random.randn(n)})\n\nxs = [-10, 0, 10]\ncvs = df.columns.values\n
Run Code Online (Sandbox Code Playgroud)\n\n

现在考虑 3 种不同的方法来附加列,这些方法将在给定列之间插入 x 坐标 5:

\n\n
%timeit df['n1'] = df.apply(lambda row: np.interp(5, xs, row[cvs]), axis=1)\n%timeit df['n2'] = df.apply(lambda row: np.interp(5, xs, tuple([row[j] for j in cvs])), axis=1)\n%timeit df['n3'] = interp1d(xs, df[cvs])(5)\n
Run Code Online (Sandbox Code Playgroud)\n\n

以下是 n=1e2 的结果:

\n\n
100 loops, best of 3: 13.2 ms per loop\n1000 loops, best of 3: 1.24 ms per loop\n1000 loops, best of 3: 488 \xc2\xb5s per loop\n
Run Code Online (Sandbox Code Playgroud)\n\n

对于 n=1e4:

\n\n
1 loops, best of 3: 1.33 s per loop\n10 loops, best of 3: 109 ms per loop\n1000 loops, best of 3: 798 \xc2\xb5s per loop\n
Run Code Online (Sandbox Code Playgroud)\n\n

对于 n=1e6:

\n\n
# first one is too slow to wait for\n1 loops, best of 3: 10.9 s per loop\n10 loops, best of 3: 58.3 ms per loop\n
Run Code Online (Sandbox Code Playgroud)\n\n

一个后续问题:是否有一种快速方法来修改此代码,以便它可以通过线性外推处理训练数据的最小-最大范围之外的 x 输入?

\n