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

Python 在每行中给定值的不同数据帧之间进行线性插值,python,pandas,numpy,dataframe,interpolation,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_chin

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

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)
然后,我们将为美国(苹果美国)、欧洲(苹果欧盟)等提供同等的服务

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

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_投资组合['country']中的值,例如,如果是'china',则需要天数(第[0]行中的12天)并在Apple_china数据框内进行线性插值。因此,第[0]行的值介于5.1和6.2之间,第[3]行的值介于6.2和7.1之间,依此类推

对于第[1]行,它将查看类似的Apple_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)

但是它返回了一个x范围的
ValueError

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

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

步骤1

创建一个字典,将国家映射到您所在国家的特定数据

country_map = {'china': apples_china.sort_values('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

谢谢你,jpp。我认为一个小的修正是在插值函数中,np.interp(days,mapper[country][days],mapper[country].iloc[:,0]。值而不是mapper[country]['apples\u china'。一旦我们添加更多的国家,值就会变为。