Pandas在每行给定值的不同数据帧之间进行线性插值

时间:2018-04-18 08:30:26

标签: python pandas numpy dataframe interpolation

根据期限,我们在不同国家(例如,中国,美国,印度等)的苹果价格有一些数据框,如下所示。 以中国为例:

tenors = pd.Series(['1W', '1M', '1Y'])
apples_china = pd.Series([5.1, 6.2, 7.1])
days = pd.Series([7, 30, 365])
data = {'tenors': tenors, 
   'apples_china':  apples_china,
   'days' : days}
apples_china = pd.DataFrame(data)

然后我们会有相同的美国(apples_usa),欧洲(apples_eu)等。

然后我们有一个更大的投资组合'数据框看起来像:

country = pd.Series(['china', 'usa', 'europe',' china', 'china', 'india'])
days = pd.Series([12, 45, 99, 101, 102, 300 ])
portfolio = {'country': country, 
   'days' : days}
df_portfolio = pd.DataFrame(portfolio)

我想添加一栏:

df_portfolio['price']

查看df_portfolio [' country']中的值,如果是' china'例如,获取天数(行[0]中的12天)并在apples_china数据帧内线性插值。因此,它将在行[0]上的值介于5.1和6.2之间,行[3]上的值介于6.2和7.1之间,依此类推。

对于行[1],它将查看类似的apples_usa数据框等。

我尝试的是:

from scipy.interpolate import interp1d
test = interp1d(apples_china['apples_china'], apples_china['days']) #arrays Y and X 
df_portfolio['price'] = np.where(df_portfolio['country']=='china', test(df_portfolio['days']), 0)

但它返回了ValueError的x范围。

1 个答案:

答案 0 :(得分:1)

有两种选择的解决方案适合numpy.where治疗。

但是,对于涉及许多国家/地区的可扩展解决方案,字典可能更有用。下面我列出了必要的步骤:

第1步

根据您所在国家/地区的数据创建字典映射国家/地区。

country_map = {'china': apples_china.sort_values('days')}

请注意,我们需要确保您的国家/地区数据框按days排序,以确保步骤2中的np.interp按要求运行。

第2步

定义一个自定义函数,它从您的投资组合数据框中获取一行数据,并从步骤1中获取映射字典,然后使用np.interp执行映射。您可以使用try / except子句来捕获字典中不存在某个国家/地区的实例。

def interpolator(row, mapper):
    days = row['days']
    country = row['country']
    try:
        return np.interp(days, mapper[country]['days'].values,
                         mapper[country]['apples_china'].values)
    except KeyError:
        return np.nan

第3步

使用pd.DataFrame.apply逐行应用第2步中的功能。

df_portfolio['price'] = df_portfolio.apply(interpolator, mapper=country_map, axis=1)

<强>结果

print(df_portfolio)

  country  days     price
0   china    12  5.339130
1     usa    45       NaN
2  europe    99       NaN
3   china   101  6.390746
4   china   102  6.393433
5   india   300       NaN