微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

大熊猫在组内变化一年

如何解决大熊猫在组内变化一年

我希望在 Pandas 中创建一个滞后的年度回报变量。

到目前为止我已经尝试过:

df_ret_lagged = df_ret.set_index(['year','cusip'])
df_ret_lagged['yearly_ret_lag'] = df_ret_lagged['year_ret'].shift(12)
df_ret_lagged.reset_index(inplace = True) 

然而,这只是将年度回报向下移动 12 行,而不是按分组。下面的数据框显示代码所做的事情。

    year    cusip        date       year_ret    yearly_ret_lag
0   1983    000165100   1983-09-01  0.183673    NaN
1   1983    000165100   1983-10-01  0.183673    NaN
2   1983    000165100   1983-11-01  0.183673    NaN
3   1983    000165100   1983-12-01  0.183673    NaN
4   1984    000165100   1984-01-01  -0.482758   NaN
5   1984    000165100   1984-02-01  -0.482758   NaN
6   1984    000165100   1984-03-01  -0.482758   NaN
7   1984    000165100   1984-04-01  -0.482758   NaN
8   1984    000165100   1984-05-01  -0.482758   NaN
9   1984    000165100   1984-06-01  -0.482758   NaN
10  1984    000165100   1984-07-01  -0.482758   NaN
11  1984    000165100   1984-08-01  -0.482758   NaN
12  1984    000165100   1984-09-01  -0.482758   0.183673
13  1984    000165100   1984-10-01  -0.482758   0.183673
14  1984    000165100   1984-11-01  -0.482758   0.183673
15  1984    000165100   1984-12-01  -0.482758   0.183673
16  1985    000165100   1985-01-01  1.700000    -0.482758
17  1985    000165100   1985-02-01  1.700000    -0.482758
18  1985    000165100   1985-03-01  1.700000    -0.482758
19  1985    000165100   1985-04-01  1.700000    -0.482758

理想情况下,我希望 1983 year_ret 填满 1984 年的所有日期,依此类推。此外,这些必须按 cusip(公司标识符)分组。

谢谢!

解决方法

我使用了 for 循环:

for year in df['year'].unique()[1:]: #list of all the years except the first
    df.loc[df['year'] == year,'year_ret_lag'] = df.loc[df['year'] == year-1,'year_ret'].iloc[0]

df

    year    cusip   date        year_ret    year_ret_lag
0   1983    165100  01/09/1983  0.183673    NaN
1   1983    165100  01/10/1983  0.183673    NaN
2   1983    165100  01/11/1983  0.183673    NaN
3   1983    165100  01/12/1983  0.183673    NaN
4   1984    165100  01/01/1984  -0.482758   0.183673
5   1984    165100  01/02/1984  -0.482758   0.183673
6   1984    165100  01/03/1984  -0.482758   0.183673
7   1984    165100  01/04/1984  -0.482758   0.183673
8   1984    165100  01/05/1984  -0.482758   0.183673
9   1984    165100  01/06/1984  -0.482758   0.183673
10  1984    165100  01/07/1984  -0.482758   0.183673
11  1984    165100  01/08/1984  -0.482758   0.183673
12  1984    165100  01/09/1984  -0.482758   0.183673
13  1984    165100  01/10/1984  -0.482758   0.183673
14  1984    165100  01/11/1984  -0.482758   0.183673
15  1984    165100  01/12/1984  -0.482758   0.183673
16  1985    165100  01/01/1985  1.700000    -0.482758
17  1985    165100  01/02/1985  1.700000    -0.482758
18  1985    165100  01/03/1985  1.700000    -0.482758
19  1985    165100  01/04/1985  1.700000    -0.482758
,

我想这可能就是您要的。请注意,这依赖于提前对数据框进行正确排序和结构化(例如,每个月都有条目)。

这会在移动之前按 cusip 和 date 对所有内容进行排序,然后通过用 nans 覆盖它们来擦除 cusips 之间不匹配的值。然后您可以使用 .fillna(method='bfill') 获取其中较早的值。

df_new = df_ret.sort_values(['cusip','date'])
df_new['yearly_ret_lag'] = df_new['year_ret'].shift(12)
df_new.loc[ (df_new['cusip'] != df_new['cusip'].shift(12)),'yearly_ret_lag'] = np.nan
df_new['yearly_ret_lag'] = df_new['yearly_ret_lag'].fillna(method='bfill')
,

另一个没有循环的解决方案,它让你有可能丢失月份,或者 groupby cusid 是:

df 的构建:

dates = pd.date_range("1983-09-01","1985-12-31",freq="1M")
df = pd.DataFrame(index =dates,columns=["Year","cusip","year_ret"])
df['Year'] = df.index
df['Year'] = df['Year'].dt.strftime(date_format='%Y')
df['cusip'] = '01234'
df['year_ret'] =[0.183673,0.183673,-0.482758,1.700000,1.700000]

还有代码:

#### First,condition if year changes
_condition_1 = df.Year != df.Year.shift(1)

#### If condition is True,put the past ret as new
df['lag'] = np.where(_condition_1,df['year_ret'].shift(1),np.nan)

#### Fill the nan,and it's ok
df = df.fillna(method='ffill')

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。