Pandas 在每行给定值的不同数据帧之间进行线性插值
Pandas linear interpolate between different dataframes given values in each row
我们有几个不同国家(比如中国、美国、印度等)根据期限的苹果价格数据框,如下所示。
以中国为例:
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) 等提供等效的
然后我们有一个更大的 'portfolio' 数据框,如下所示:
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 范围。
有几个选项的解决方案适合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
我们有几个不同国家(比如中国、美国、印度等)根据期限的苹果价格数据框,如下所示。 以中国为例:
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) 等提供等效的
然后我们有一个更大的 'portfolio' 数据框,如下所示:
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 范围。
有几个选项的解决方案适合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