编辑摘要 所以我有:p1 数据框,其中包含过去 5 年的 n 种金融工具的价格和回报:
Date a_price b_price a_ret b_ret
0 2018-04-13 6.335 5.114 0.0047 0.01
.
.
.
1272 2023-04-13 11.525 5.708 0.0039 -0.04
然后我有另一个数据框种子,它只包含一个日期和相同 n-instruments 的标准偏差
Date a_SD b_SD
63 2023-04-13 0.019 0.017
在 p1 中,我需要创建 n 个新列 EWMA,如下所示: 对于 p1 (2018-04-13) 中最早的日期,a_EWMA = X*(seed[a_SD]**2) + (1-X) *(p1[a_Ret]*2) 对于任何其他日期 a_EWMA = X(p1.loc[i-1,a_EWMA]**2) + (1-X) *(p1[a_Ret]**2).
想要的输出是p1如下:
Date a_price b_price a_ret b_ret a_EWMA b_EWMA
0 2018-04-13 6.335 5.114 0.0047 0.01 ... ...
.
.
.
1272 2023-04-13 11.525 5.708 0.0039 -0.04 ... ...
由于我需要自动化,我正在尝试使用 f'{col} 来匹配 2 个数据帧,但我认为我没有正确执行。 我用下面的函数来做,但它给了我所有的 None 结果,最糟糕的是它创建了太多的列,而它应该只创建 n-more(本例中为 2)
def EWMA(x):
for i in p1.index:
if p1.loc[i,'Date'] == min_Date and '_SD' in seed.columns:
return math.sqrt((lam*(seed[[f'{col}_SD'for col in seed.columns]])**2) + (1-lam) * (p1.loc[i,[f'{col}_Ret' for col in p1.columns]]**2))
elif p1.loc[i,'Date'] != min_Date and '_SD' in seed.columns:
return math.sqrt(lam*((p1.loc[i-1,[f'{col}_EWMA'for col in p1.columns]])**2)+(1-lam)*(p1.loc[i,[f'{col}_Ret'for col in p1.columns]]**2)) if f'_Ret' in p1.columns:
p1[[f'{col}_EWMA'for col in p1.columns]] = p1.apply(EWMA)
您的问题最初提到了与数据相关的日期,而您的种子值数据框仍然包含一个似乎与解决方案无关的日期。因此,我忽略了日期,假设源数据每天都有一条记录并且种子值中的日期无关紧要(因为源数据无论如何都从该日期开始)。
考虑到这一点:
import datetime, random
import pandas as pd
import numpy as np
# random example data, structured like yours
dates = pd.date_range(datetime.date(2018, 4, 13), datetime.date(2023, 4, 13), freq='D')
df = pd.DataFrame(
np.hstack([np.random.rand(len(dates), 2) * 10, np.random.rand(len(dates), 2)]),
index=dates, columns=['a_price', 'b_price', 'a_ret', 'b_ret']
)
print(df)
# seed values (apparently standard deviations), date did not seem relevant to the example
seed_df = pd.DataFrame([{'a_SD': 0.019, 'b_SD': 0.017}])
print(seed_df)
def ewma(x, seed, ys):
# generic EWMA with some seed value
v = seed
return [v := x*y + (1-x)*v for y in ys]
for col in seed_df.columns:
df[f'{col[:-3]}_ewma'] = ewma(
0.5, # an arbitrary 'X', or lambda value for the EWMA
seed_df[col][0]**2, # the seed value for the column, getting [0] because it's a series, squared
df[f'{col[:-3]}_ret']**2 # the column of returns squared, as you want them squared
)
print(df)
这导致了我认为你所要求的。如果日期与您最初的问题有某种相关性,您应该更新问题以更清楚地了解它们的含义。
此外,如果您的输入数据不像我在这里生成的示例数据那么简单,并且这会导致问题,您应该更具体地说明它可能有何不同。
此处的示例对种子值和为其创建 EWMA 列的变量进行平方,因为您指定这是问题中需要的 -
ewma()
函数无论如何都适用。