【问题标题】:Dateframe interpolate not working in Panda + multidimensional interpolation数据帧插值在 Panda + 多维插值中不起作用
【发布时间】:2018-06-12 14:24:20
【问题描述】:

数据帧不工作的多维插值

import pandas as pd
import numpy as np
raw_data = {'CCY_CODE': ['SGD','USD','USD','USD','USD','USD','USD','EUR','EUR','EUR','EUR','EUR','EUR','USD'],
            'END_DATE': ['16/03/2018','17/03/2018','17/03/2018','17/03/2018','17/03/2018','17/03/2018','17/03/2018',
                        '17/03/2018','17/03/2018','17/03/2018','17/03/2018','17/03/2018','17/03/2018','17/03/2018'],
            'STRIKE':[0.005,0.01,0.015,0.02,0.025,0.03,0.035,0.04,0.045,0.05,0.55,0.06,0.065,0.07],
            'VOLATILITY':[np.nan,np.nan,0.3424,np.nan,0.2617,0.2414,np.nan,np.nan,0.215,0.212,0.2103,np.nan,0.2092,np.nan]
           }
df_volsurface = pd.DataFrame(raw_data,columns = ['CCY_CODE','END_DATE','STRIKE','VOLATILITY'])
df_volsurface['END_DATE'] = pd.to_datetime(df_volsurface['END_DATE'])
df_volsurface.interpolate(method='akima',limit_direction='both')

输出:

<table><tbody><tr><th> </th><th>CCY_CODE</th><th>END_DATE</th><th>STRIKE</th><th>VOLATILITY</th></tr><tr><td>0</td><td>SGD</td><td>3/16/2018</td><td>0.005</td><td>NaN</td></tr><tr><td>1</td><td>USD</td><td>3/17/2018</td><td>0.01</td><td>NaN</td></tr><tr><td>2</td><td>USD</td><td>3/17/2018</td><td>0.015</td><td>0.3424</td></tr><tr><td>3</td><td>USD</td><td>3/17/2018</td><td>0.02</td><td>0.296358</td></tr><tr><td>4</td><td>USD</td><td>3/17/2018</td><td>0.025</td><td>0.2617</td></tr><tr><td>5</td><td>USD</td><td>3/17/2018</td><td>0.03</td><td>0.2414</td></tr><tr><td>6</td><td>USD</td><td>3/17/2018</td><td>0.035</td><td>0.230295</td></tr><tr><td>7</td><td>EUR</td><td>3/17/2018</td><td>0.04</td><td>0.220911</td></tr><tr><td>8</td><td>EUR</td><td>3/17/2018</td><td>0.045</td><td>0.215</td></tr><tr><td>9</td><td>EUR</td><td>3/17/2018</td><td>0.05</td><td>0.212</td></tr><tr><td>10</td><td>EUR</td><td>3/17/2018</td><td>0.55</td><td>0.2103</td></tr><tr><td>11</td><td>EUR</td><td>3/17/2018</td><td>0.06</td><td>0.209471</td></tr><tr><td>12</td><td>EUR</td><td>3/17/2018</td><td>0.065</td><td>0.2092</td></tr><tr><td>13</td><td>USD</td><td>3/17/2018</td><td>0.07</td><td>NaN</td></tr></tbody></table>

预期结果:

<table><tbody><tr><th> </th><th>CCY_CODE</th><th>END_DATE</th><th>STRIKE</th><th>VOLATILITY</th></tr><tr><td>0</td><td>SGD</td><td>3/16/2018</td><td>0.005</td><td>NaN</td></tr><tr><td>1</td><td>USD</td><td>3/17/2018</td><td>0.01</td><td>Expected some logical value</td></tr><tr><td>2</td><td>USD</td><td>3/17/2018</td><td>0.015</td><td>0.3424</td></tr><tr><td>3</td><td>USD</td><td>3/17/2018</td><td>0.02</td><td>0.296358</td></tr><tr><td>4</td><td>USD</td><td>3/17/2018</td><td>0.025</td><td>0.2617</td></tr><tr><td>5</td><td>USD</td><td>3/17/2018</td><td>0.03</td><td>0.2414</td></tr><tr><td>6</td><td>USD</td><td>3/17/2018</td><td>0.035</td><td>0.230295</td></tr><tr><td>7</td><td>EUR</td><td>3/17/2018</td><td>0.04</td><td>0.220911</td></tr><tr><td>8</td><td>EUR</td><td>3/17/2018</td><td>0.045</td><td>0.215</td></tr><tr><td>9</td><td>EUR</td><td>3/17/2018</td><td>0.05</td><td>0.212</td></tr><tr><td>10</td><td>EUR</td><td>3/17/2018</td><td>0.55</td><td>0.2103</td></tr><tr><td>11</td><td>EUR</td><td>3/17/2018</td><td>0.06</td><td>0.209471</td></tr><tr><td>12</td><td>EUR</td><td>3/17/2018</td><td>0.065</td><td>0.2092</td></tr><tr><td>13</td><td>USD</td><td>3/17/2018</td><td>0.07</td><td>Expected some logical value</td></tr></tbody></table>

线性插值方法在不考虑 ccy_code 的情况下将最后一个可用值复制到所有后向和前向缺失值

df_volsurface.interpolate(method='linear',limit_direction='both')

输出:

<table><tbody><tr><th>CCY_CODE</th><th>END_DATE</th><th>STRIKE</th><th>VOLATILITY</th><th> </th></tr><tr><td>0</td><td>SGD</td><td>3/16/2018</td><td>0.005</td><td>0.3424</td></tr><tr><td>1</td><td>USD</td><td>3/17/2018</td><td>0.01</td><td>0.3424</td></tr><tr><td>2</td><td>USD</td><td>3/17/2018</td><td>0.015</td><td>0.3424</td></tr><tr><td>3</td><td>USD</td><td>3/17/2018</td><td>0.02</td><td>0.30205</td></tr><tr><td>4</td><td>USD</td><td>3/17/2018</td><td>0.025</td><td>0.2617</td></tr><tr><td>5</td><td>USD</td><td>3/17/2018</td><td>0.03</td><td>0.2414</td></tr><tr><td>6</td><td>USD</td><td>3/17/2018</td><td>0.035</td><td>0.2326</td></tr><tr><td>7</td><td>EUR</td><td>3/17/2018</td><td>0.04</td><td>0.2238</td></tr><tr><td>8</td><td>EUR</td><td>3/17/2018</td><td>0.045</td><td>0.215</td></tr><tr><td>9</td><td>EUR</td><td>3/17/2018</td><td>0.05</td><td>0.212</td></tr><tr><td>10</td><td>EUR</td><td>3/17/2018</td><td>0.55</td><td>0.2103</td></tr><tr><td>11</td><td>EUR</td><td>3/17/2018</td><td>0.06</td><td>0.20975</td></tr><tr><td>12</td><td>EUR</td><td>3/17/2018</td><td>0.065</td><td>0.2092</td></tr><tr><td>13</td><td>USD</td><td>3/17/2018</td><td>0.07</td><td>0.2092</td></tr></tbody></table>

感谢任何帮助!谢谢!

【问题讨论】:

  • 您可以在调用 interpolate 之前发布一个数据帧示例df_volsurface 吗?
  • 嗨 WolfgangK,感谢您提供帮助。按要求更新。
  • 从你发的图片来看,没有缺失数据。如果您在两个都为 0 的值之间进行插值,则结果仍然为 0。作为一般提示,请让我们轻松地为您提供帮助:将数据样本以我们可以复制和粘贴的形式保存会很棒重现您的错误。此外,显示您预期的结果。由于没有人拥有您的 csv 文件,因此数据准备的代码对其他人来说几乎毫无意义。也许看看How to create a Minimal, Complete, and Verifiable example
  • WolfgangK,正如我所建议的那样,我改变了我的问题。另外,感谢您先前关于 0. 0 的评论,需要在插值之前转换 NaN,这现在可以工作,但发布时存在一些问题。谢谢!
  • 我猜您的'STRIKE' 列中有错字(0.55 应该是 0.055)。

标签: python pandas dataframe interpolation


【解决方案1】:

我想指出,这仍然是一维插值。我们有一个自变量('STRIKE')和一个因变量('VOLATILITY')。针对不同的条件进行插值,例如对于每一天,每种货币,每种场景等。下面是一个如何基于'END_DATE'和'CCY_CODE'进行插值的示例。

# set all the conditions as index
df_volsurface.set_index(['END_DATE', 'CCY_CODE', 'STRIKE'], inplace=True)
df_volsurface.sort_index(level=['END_DATE', 'CCY_CODE', 'STRIKE'], inplace=True)
# create separate columns for all criteria except the independent variable
df_volsurface = df_volsurface.unstack(level=['END_DATE', 'CCY_CODE'])
for ccy in df_volsurface:
    indices = df_volsurface[ccy].notna()
    if not any(indices):
        continue  # we are not interested in a column with only NaN
    x = df_volsurface.index.get_level_values(level='STRIKE')  # independent var
    y = df_volsurface[ccy]  # dependent var
    # create interpolation function
    f_interp = scipy.interpolate.interp1d(x[indices], y[indices], kind='linear', 
                            bounds_error=False, fill_value='extrapolate')
    df_volsurface['VOL_INTERP', ccy[1], ccy[2]] = f_interp(x)
print(df_volsurface)

其他条件的插值应该类似地工作。这是生成的 DataFrame:

         VOLATILITY                    VOL_INTERP         
END_DATE 2018-03-16 2018-03-17         2018-03-17         
CCY_CODE        SGD        EUR     USD        EUR      USD
STRIKE                                                    
0.005           NaN        NaN     NaN    0.23900  0.42310
0.010           NaN        NaN     NaN    0.23600  0.38275
0.015           NaN        NaN  0.3424    0.23300  0.34240
0.020           NaN        NaN     NaN    0.23000  0.30205
0.025           NaN        NaN  0.2617    0.22700  0.26170
0.030           NaN        NaN  0.2414    0.22400  0.24140
0.035           NaN        NaN     NaN    0.22100  0.22110
0.040           NaN        NaN     NaN    0.21800  0.20080
0.045           NaN     0.2150     NaN    0.21500  0.18050
0.050           NaN     0.2120     NaN    0.21200  0.16020
0.055           NaN     0.2103     NaN    0.21030  0.13990
0.060           NaN        NaN     NaN    0.20975  0.11960
0.065           NaN     0.2092     NaN    0.20920  0.09930
0.070           NaN        NaN     NaN    0.20865  0.07900

使用df_volsurface.stack() 返回您选择的多索引。还有几种pandas插值方法可供选择。但是,我还没有使用method='akima' 为您的问题找到令人满意的解决方案,因为它只在给定的数据点之间进行插值,但似乎没有外推。

【讨论】:

  • 我们是否需要在插值之前使用CCY_CODE 列进行分组?
  • @AbhishekMishra 您需要为每种货币单独插值吗?您的“预期输出”没有这样显示,所以我没有打扰。您能否详细说明您正在尝试做什么并相应地更新您的问题?
  • 在问题中,user9930820 提到了Linear interpolation methods gives copy last available values to all backward and forward missing value without considering ccy_code。所以我想,user9930820 想考虑 ccy_code 进行插值。
  • @AbhishekMishra 你可能是对的。在我看来,OP 的主要关注点似乎是没有使用 akima 方法进行推断,或者只是使用 linear 重复了值。
  • @AbhisekMishra 更新了上面的问题列表,提供了更多详细信息。我更喜欢 Akima,因为它与预期结果相匹配,但我也想了解如何在没有聚合数据的情况下进行多用途插值,例如给定 t、u、v、x、y 插值 z。
猜你喜欢
  • 1970-01-01
  • 2021-11-30
  • 2012-03-20
  • 2016-08-31
  • 1970-01-01
  • 2021-10-31
  • 2017-09-19
  • 2016-04-23
  • 1970-01-01
相关资源
最近更新 更多