这篇文章介绍了Fama 三因子和Carhat 四因子,主要是在介绍Fama三因子,因为Carhat四因子,只是三因子的拓展。
并且,计算方法是我对两篇文章的学习注解,可以先去看原文章。

本篇文章学习参考资料有:
[1] 刘媛媛. 中国股票市场的有效性实证研究[D].西南财经大学,2012.
[2] 张庄昊. 改进动量因子的四因子量化投资方案策划[D].上海师范大学,2018.
[3] Carhart四因子模型A股实证(附源码)
[4] Fama-French三因子回归A股实证(附源码)

先唠叨一下自己的一些观点:
我的理解是这些模型设计的初中是为了解释投资组合(股票)的收益率来源。
如:Markowtiz(1952)投资组合理论认为收益率是对风险的补充;
Sharp(1964)、Lintner(1965)和Mossin(1966)提出的资本资产定价模型(CAPM),认为收益率对系统风险的补充;
Fama和French(1993)提出三因子模型,是认为收益率来自于市值规模、账面市值比、市场风险(系统风险)
Carhart 提出四因子模型,是认为收益率来自市值规模、账面市值比、市场风险(系统风险)以及动量效应
本人理解模型本质都是探讨收益率来自于什么,或者说是受何因素影响。认识有限,若有错误,欢迎指正~

好啦,现在进入正文~

1 Fama三因子

1.1 Fama三因子的出现

1.1.1 投资组合理论

Markowtiz(1952)投资组合理论核心观点:1)提出利用证券投资收益率的方差作为衡量风险的指标;2)将风险分为两类,一类是通过多样的资产组合可分散消除的风险,称为非系统风险;另一类是不能用资产组合分散的风险称为系统风险;2)风险水平确定的情况下来选择具有最高收益率的投资组合集合,或者在给定收益率水平下,选择具有最小风险的投资组合集合。
在这里插入图片描述

1.1.2 资本资产定价模型

Sharp(1964)、Lintner(1965)和Mossin(1966)提出资本资产定价模型(CAPM)核心观点:1)股票的预期收益率与其风险成正相关关系,投资股票的收益被视为投资者投资某股票所承担的风险的补偿;2)风险资产的收益等于无风险资产收益加上风险升水。即高风险伴随高收益,系统风险用β来衡量;3)β是股票收益对整个市场组合收益的影响(是衡量系统性风险的指标),可作为单个股票收益率变动的敏感性指标。4)换言之,在有效资产组合中,非系统风险能被多样化分散投资消除,而系统风险不会因为投资的多样化而被分散消除,因此资产组合的期望收益率仅与资产组合的系统风险相关

在这里插入图片描述
在这里插入图片描述

过于严苛的假设条件后的发展:1)无风险资产不存在时的零资本资产定价模型;2)考虑税收的资本资产定价模型;3)跨期的资本资产定价模型;4)套利定价理论。
仅用β系数来衡量系统风险,在各种异象的冲击下越发丧失对股票收益的解释力度

1.1.3 Fama三因子出现

研究学者们开始思考,用单个系统因子来解释股票收益率或许并不是合理的。风险有可能受多维因子影响。如:

Basu(1977)的研究表明,盈余价格比因子对股票收益率有显著的影响。他认为低市盈率的股票收益率明显高于高市盈率的股票。即市盈率对股票横截面收益的解释力可以吸收规模和市场β的解释能力。

Vipul(1998)检测公司基本面的因子对股票收益率的影响,如公司规模因子对公司的系统风险有相当大的影响。

Fama和French在1992年用美国股票市场从1929年至1963年的数据作为样本,研究了上市公司市值(ME)和账面市值比(BE/ME)对股票价格变动及其收益率的解释能力。这种现象是资本资产定价模型描述以外的。

1.2 Fama三因子的介绍

Fama和French(1993)首次提出三因子模型,把股票的账面市值比率以及规模因子作为除β以外对股票收益的解释因子。

1.2.1 核心观点

1)在原始资本资产定价模型的基础上增加市值规模因子和账面市值比因子比作为市场风险因素的补充,能够更完整的描述单个股票所包含的投资风险。
2)公司规模和账面市值比这两个因子能够很好的捕捉股票平均收益率,并且杠杆效应(leverage)和收入价格比效应(earning-price ratio E/P)对股票横截面收益的解释能力被规模因子(size)和账面市值比因子(book to market ratio)吸收了。

1.2.2 原理及模型

在这里插入图片描述
ai: 截距项表示单个选定股票或者投资组合i的无条件限制的平均收益,如果a在置信区间内等于0,说明三个风险因子基本能够解释研究样本股票的平均横截面收益;
Ri :是股票或投资组合i的收益率
Rf :是无风险收益率
et : 是误差项
Ri - Rf :是某选定股票或投资组合的超额收益(投资组合的收益率,Fama论文中是使用doublesort的方法构建了25个投资组合)

MKT**(市场风险因子)** : Rm(所有组合里的股票的加权回报) – Rf(无风险收益率),是整个市场组合的超额收益

SMB和HML构成步骤
1)规模组合的构建,按照股票的市价把样本分为大规模公司(big firm),中规模公司(medium firm)和小规模公司(small firm)。然后将公司的账面市值比按由高到低的顺序将股票分为高(High)、中(Medium)、低(Low)三个组合;
2)然后将公司规模和账面市值比组合成6个投资组合:小公司小账面市值比(S/L)、小公司中账面市值比(S/M)、小公司高账面市值比(S/H),大公司小账面市值比(B/L),大公司中账面市值比(B/M)、大公司高账面市值比(B/H)。
3)SMB(规模因子)和HML(账面市值比因子)公式:
在这里插入图片描述
SMB因子涉及到规模因子的风险,同时排除账面市值比因子的影响;同理,HML因子只涉及到账面市值比因子风险。

1.3 Fama三因子的计算

参考学习: Fama-French三因子回归A股实证(附源码)

数据来源(学习的文章)
1)HML、SMB、因变量:使用2009年-2019年全A股月度数据进行计算(用其他频率也可)
2)MKT:MKT的计算比较简单,直接使用中国资产管理研究中心提供的数据了,当然如果想自己算的话,RM可以考虑用中证全指的收益率,RF可以用10年期国债到期收益率。
总的来说,数据包括:以月份为频率的股票的股价(price)、股票的市值(mkt)、股票的市净率(pb)、MKT因子

计算部分开始
(1)数据处理

"""首先把账面市值比BM和市值mkt数据拼在一起,然后剔除新股和ST股"""
price = pd.read_csv('复权价格.csv')  # 每股股价
ST = pd.read_csv('ST.csv') # st数据
pb = pd.read_csv('PB.csv')  # 市净率(市价账面比)数据
mkt = pd.read_csv('mkt.csv')  # 股票总市值数据
ipodate = pd.read_csv('上市日期.csv') # 上市日期
# 日期处理
price['tradedate'] = pd.to_datetime(price.tradedate)  
ST['entry_dt'] = pd.to_datetime(ST.entry_dt) 
ST['remove_dt'] = pd.to_datetime(ST.remove_dt) 
mkt['tradedate'] = pd.to_datetime(mkt.tradedate) 
pb['tradedate'] = pd.to_datetime(pb.tradedate)
ipodate['ipodate'] = pd.to_datetime(ipodate.ipodate) 
BM = pb.copy() 
BM['BM'] = 1/BM.pb  # 先将市值账面比倒数为账面市值比
BM = BM.drop(['pb'],axis = 1)  # 丢掉市值账面比变量
f = pd.merge(BM,mkt,left_on = ['tradedate','stockcode'],right_on = ['tradedate','stockcode'])  # 将账面市值比数据和市值数据依据股票代码和日期进行合并
# 踢PB为负的 
f = f.loc[f.BM > 0].reset_index(drop = True) # 选择BM>0的,然后把小于0的剔除,重新排序索引
# 踢新股:上市不满一年
ipodate['entry_date'] = ipodate.ipodate + datetime.timedelta(365)  # ipo日期 + 365天 确定一年后的日期
f = pd.merge(f,ipodate,left_on = ['stockcode'],right_on = ['stockcode']) # 合并ipo和f数据
f = f.loc[f.tradedate >= f.entry_date].reset_index(drop = True) # 选择上市满一年的,然后把不满的剔除,重新排序索引
f = f.drop(['ipodate','entry_date'],axis = 1)  # f现在有的变量:代码、tradedata、BM、mkt
# 剔ST
res =[]

for dates in f.tradedate.unique(): # dates = f.tradedate.unique()[10] 交易日期去重
    fuse = f.loc[f.tradedate == dates]     
    st_use = ST.loc[ST.entry_dt <= dates] # 交易日期前进入st
    st_use = st_use.loc[(st_use.remove_dt > dates) | pd.isnull(st_use.remove_dt)]  # 交易日期内还在st或者移除st日期未写的定义为st
    scode_notst = set(fuse.stockcode).difference(set(st_use.stockcode))  
    fuse = fuse.set_index(['stockcode']).loc[scode_notst].reset_index() 
    res.append(fuse)

res = pd.concat(res,axis = 0) # 拼接
f = res.reset_index(drop = True)

(2)生成6个投资组合

"""
接下来生成6个投资组合:
(1)获取所有年份5月末的数据作为分组依据
(2)按市值分为两组,
(3)按账面市值比生成三组。
以上过程通过函数split_SIZE和split_BM实现,
通过apply和groupby得到每一期的分组。
"""
f['ym'] = f.tradedate.apply(lambda x:x.year*100 + x.month)  # 设置年月变量ym
f_5 = f.loc[f.ym %10 ==5].copy()  # 取所有年份5月末的数据
"""账面市值比分组:H、M、L"""
def split_BM(x):
    x.loc[x['BM'] >= x.BM.quantile(0.7),'group_BM'] = 'H'  # 建立group_BM组,大于等于BMt0.7数,定义为H
    x.loc[x['BM'] < x.BM.quantile(0.3),'group_BM'] = 'L'
    return x
 
f_5['group_BM'] = 'M'  
f_5 = f_5.groupby(['ym']).apply(split_BM) #  匹配得到,划分为H、L、M 
f_5 = f_5.reset_index(drop = True)
"""市值分组:B、S"""
def split_SIZE(x):
    x.loc[x['mkt'] >= x.mkt.median(),'group_SIZE'] = 'B'  # 建立group_SIZE组,大于等于mkt中位数,定义为B
    return x


f_5['group_SIZE'] = 'S' 
f_5 = f_5.groupby(['ym']).apply(split_SIZE)
f_5 = f_5.rename(columns = {'ym':'portfolio_dates'})  # 投资组合日期 yyyy05
f_5 = f_5[['stockcode','portfolio_dates','group_BM','group_SIZE']]  # f_5有如下变量
f['portfolio_dates'] = f.tradedate.apply(lambda x:x.year*100 + 5 if x.month > 5 else  (x.year - 1)*100 + 5)  # 小于5月为上年的5月末表现和大于5月为本年的5月末表现

f = pd.merge(f,f_5,left_on =['stockcode','portfolio_dates'],right_on =['stockcode','portfolio_dates']) # f和f_5数据合并,得到H、L、M和B、S
f = f.reset_index(drop = True)

f['portfolio_name'] = f.group_SIZE + '/' + f.group_BM  # 生成portfolio_name变量

在这里插入图片描述
(3)计算这六个组合的市值加权收益率(Value-weighted return)

# 先计算每个股票的股价增长率(股票收益率)
"""df.pivo用法:https://www.cnblogs.com/sunbigdata/p/8134441.html"""
"""df.stack用法:https://www.cnblogs.com/bambipai/p/7658311.html"""
ret = price.pivot(index = 'tradedate',columns = 'stockcode',values = 'price').pct_change(1).shift(-1).fillna(0)  # 计算股价增长率,缺失值补位为0
ret = ret.stack().reset_index()  # 转置成面板数据
ret = ret.rename(columns = {ret.columns[2]:'ret'})
sdate = datetime.date(2009,5,1)
f = f.loc[f.tradedate >= sdate].reset_index(drop = True) # 限制样本为2009年5月1号后
f = pd.merge(f,ret,left_on =['stockcode','tradedate'],right_on =['stockcode','tradedate'])
f.loc[f.tradedate == datetime.date(2009,5,27),'ret'] = 0 # 为什么 2009年5月27号,ret =0 ?
port_ret = f.groupby(['tradedate','portfolio_name']).apply(lambda x:(x.ret*x.mkt).sum()/x.mkt.sum()) # 计算每年每月的6个投资组合市值加权收益率
port_ret = port_ret.reset_index()
port_ret = port_ret.rename(columns = {port_ret.columns[-1]:'ret'}) # 定义每年每月的6个投资组合市值加权收益率 这个变量
# 计算这六个组合的市值加权收益率(Value-weighted return)
port_ret = f.groupby(['tradedate','portfolio_name']).apply(lambda x:(x.ret*x.mkt).sum()/x.mkt.sum()) # 计算每年每月的6个投资组合市值加权收益率
port_ret = port_ret.reset_index()
port_ret = port_ret.rename(columns = {port_ret.columns[-1]:'ret'}) # 定义每年每月的6个投资组合市值加权收益率为 这个变量ret
port_ret_pivo = port_ret.pivot(index = 'tradedate',columns = 'portfolio_name',values = 'ret')  # 由面板转为非面板 --> 转置成 6个投资组合市值加权增长率为值为变量的数据

(4)计算SMB、HML因子

# SMB因子:SMB也是每年每个月都不同的,这里是以tradedate为排序,6种组合为列变量的数据排布
# SMB = 1/3(SL + SM + SH) - 1/3(BL + BM + BH)
SMB = (port_ret_pivot['S/L'] + port_ret_pivot['S/M'] + port_ret_pivot['S/H'])/3 - (port_ret_pivot['B/L'] + port_ret_pivot['B/M'] + port_ret_pivot['B/H'])/3
# HML因子:HML也是每年每个月都不同的,这里是以tradedate为排序,6种组合为列变量的数据排布
# HML因子 HML = (SH + BH)/2 - (SL + BL)/2
HML = (port_ret_pivot['S/H'] + port_ret_pivot['B/H'])/2 - (port_ret_pivot['S/L'] + port_ret_pivot['B/L'])/2 
ff3 = pd.concat([SMB,HML],axis = 1)
ff3 = ff3.reset_index()  # 把tradedate不再设置为索引
ff3.columns = ['tradedate','SMB','HML']
ff3['ym'] = ff3.tradedate.apply(lambda x:x.year*100 + x.month)  # ff3数据已经计算出各投资组合的SMB、HML

(5)计算MKT因子

"""计算MKT因子"""
# RM:全市场流通市值加权指数收益率
# RF:无风险利率
# 这里直接用中国资产管理研究中心的数据
d = pd.read_csv('fivefactor_monthly.csv')
RM_RF = d[['trdmn','mkt_rf','rf']].copy()  # mkt_rf是全市场流通市值加权指数收益率减去无风险利率
RM_RF = RM_RF.rename(columns = {'trdmn':'ym'})
ff3 = pd.merge(ff3,RM_RF,left_on = ['ym'],right_on = ['ym'])  # 合并ff3

(6) 构造因变量

"""接下来构造因变量25个投资组合"""
# 这一次对市值和账面市值比都分别分成5等分,组合之后得到25个投资组合,并计算这25个投资组合的市值加权收益率,作为因变量。
groups = 5
f_5 = f.loc[f.ym %10 ==5,['stockcode','tradedate','ym','BM','mkt']].copy() # 还是以5月末为准
f_5['g_BM'] = f_5.BM.groupby(f_5.tradedate).apply(lambda x:np.ceil(x.rank()/(len(x)/groups))) # 按照账面市值比5等分
f_5['g_SIZE'] = f_5.mkt.groupby(f_5.tradedate).apply(lambda x:np.ceil(x.rank()/(len(x)/groups))) # 按照市值5等分
f_5 = f_5.rename(columns = {'ym':'portfolio_dates'})
f_5 = f_5[['stockcode','portfolio_dates','g_BM','g_SIZE']]
f['portfolio_dates'] = f.tradedate.apply(lambda x:x.year*100 + 5 if x.month > 5 else  (x.year - 1)*100 + 5) # 同上,小于5月,划为上年
f = pd.merge(f,f_5,left_on =['stockcode','portfolio_dates'],right_on =['stockcode','portfolio_dates'])
f = f.reset_index(drop = True)
f['portfolio_name'] = f.g_BM + '/' + f.g_SIZE  # 生成portfolio_name变量
"""计算25个组合市值加权收益率的过程同6个组合收益率过程一样"""
f = pd.merge(f,ret,left_on =['stockcode','tradedate'],right_on =['stockcode','tradedate'])
f.loc[f.tradedate == datetime.date(2009,5,27),'ret'] = 0 # 为什么 2009年5月27号,ret =0 ?
port_ret_25 = f.groupby(['tradedate','portfolio_name']).apply(lambda x:(x.ret*x.mkt).sum()/x.mkt.sum()) # 计算每年每月的25个投资组合市值加权收益率
port_ret_25 = port_ret.reset_index()
port_ret_25 = port_ret.rename(columns = {port_ret.columns[-1]:'ret_25'}) # 定义每年每月的25个投资组合市值加权收益率 这个变量
f25 = port_ret.pivot(index = 'tradedate',columns = 'portfolio_name',values = 'ret_25')  # 由面板转为非面板 --> 转置成 25个投资组合市值加权收益率为值的变量的数据
f25 = f25.reset_index()  # 把tradedate不再设置为索引

(7)解释变量数据和被解释变量数据合并

# 解释变量数据和被解释变量数据合并
f25 = pd.merge(f25,ff3,left_on = ['tradedate'],right_on = ['tradedate'])
# 最后得到的数据是每年每个月的25个投资组合的市值加权收益率、6个投资组合的HML、SML、MKT
f25['Intercept'] = 1
x = f25.loc[:,['SMB','HML','mkt_rf','Intercept']].values  # 解释变量

(8)回归

# 设置回归结果的容器
r2 = []
betas = []
t = []
p = []
# 25个投资组合依次回归
for i in range(25):# i = 0
    y = f25.loc[:,f25.columns[i+1]].values
    mod = sm.OLS(y,x).fit()

    r2.append([f25.columns[i+1],mod.rsquared])

    betas.append([f25.columns[i+1]] + list(mod.params))
    t.append([f25.columns[i+1]] + list(mod.tvalues))
    p.append([f25.columns[i+1]] + list(mod.pvalues))
p = pd.DataFrame(p,columns = ['group','SMB','HML','mkt_rf','Intercept'])
t = pd.DataFrame(t,columns = ['group','SMB','HML','mkt_rf','Intercept'])
betas = pd.DataFrame(betas,columns = ['group','SMB','HML','mkt_rf','Intercept'])
r2 = pd.DataFrame(r2,columns = ['group','r2'])

2 Carhat 四因子模型的介绍和计算

2.1 Carhat四因子模型的介绍

2.1.1 Carhat四因子的引出

伴随着在市场中的使用,Fama-French 三因子模型也被发现存在解释能力不足的问题,其并不能解释市场中动量效应存在的问题。而Carhart 四因子模型是基于 Fama-French 三因子模型而提出的。

Jegadeesh 和 Titman(1993)提出了关于股票的动量效应,即过去收益率高的股票在未来的收益率仍然要高于过去收益率较低的股票。基于此,也就有了动量交易策略,其是利用股票的动量效应突破现有趋势的一种策略。进行动量交易时,通常假设上涨的股票会持续上涨,下跌的股票会持续下跌,然后根据这个假设来执行买入和卖出。

Carhart 四因子模型是基于 Fama-French 三因子模型而提出的

2.1.2 Carhat四因子的模型

Carhart 四因子模型是基于 Fama-French 三因子模型而提出的,,模型如下:

在这里插入图片描述

因此其前三个因子,即市场因子(MKT)、规模因子(SMB)及账面市值比因子(HML)是相同的,有所不同的是加入了动量因子(UMD)

根据 Carhart 所使用的动量因子(UMD)测量方法为排序期一年,并按累计收益表现将股票同样均分为三组,前三分之一为高收益率公司(U),后三分之一为低收益率公司(D),将动量因子的期望收益设置为E(𝑈𝑀𝐷t) = 𝐸(𝑟𝑈,𝑡) − 𝐸(𝑟𝐷,𝑡)。

2.1.3 与Fama三因子的差别

从定义来看,和Fama三因子的差异主要有两点,首先是 组合是等权的Fama三因子中的组合都是市值加权的,其次 组合是月度构建的 ,三因子中的组合的年度构建的(所有年份的5月份)。

2.2 Carhat 四因子的计算

参考学习:Carhart四因子模型A股实证(附源码)
参考文章动量因子计算:用2-12个月的收益率实际上是剔除了最近1个月的收益率,原因主要在于美股市场是短期反转,长期动量的,剃掉最近1个月的反转,可以得到比较纯粹的动量。
(1)动量因子UMD 计算

"""
每月末计算所有股票前2-12个月末的收益率,构建投资组合:
(1)前30%的等权组合,后30%的等权组合,
(2)二者收益率的差值定义为动量因子,组合月度调整 。
"""
UMD = price.pivot( index = 'tradedate',columns = 'stockcode', values = 'price').pct_change(11).shift( 1).fillna( 0)  # pct_change(11)  滞后11期,计算股价增长率
UMD = UMD.stack().reset_index()
UMD = UMD. rename(columns = {UMD.columns[ 2]: 'UMD'})
# 动量因子UMD  定义按所有股票前2-12个月末的收益率分类
def split_UMD( x):
     x. loc[ x[ 'UMD'] >= x.UMD.quantile( 0.7), 'group_UMD'] = 'UMD_H'
     x. loc[ x[ 'UMD'] < x.UMD.quantile( 0.3), 'group_UMD'] = 'UMD_L'
     return  x
f[ 'group_UMD'] = 'UMD_M'  # 生成变量 'UMD_M'
f = pd.merge( f,UMD,left_on =[ 'stockcode', 'tradedate'],right_on =[ 'stockcode', 'tradedate']) # 合并股价增长率
f = f .groupby([ 'ym']).apply(split_UMD) # 按照年月来进行动量因子分组
# UMD因子 注意:组合是等权的 ,Fama三因子中的组合都是市值加权的
UMD_ret = f.groupby([ 'tradedate', 'group_UMD']).apply(lambda x:x.UMD.mean()) # 计算每年每月各组的动量因子  
UMD_ret = UMD_ret.reset_index()
UMD_ret = UMD_ret.rename(columns = {UMD_ret.columns[- 1]: 'ret'})
# UMD因子 注意:组合是等权的 ,Fama三因子中的组合都是市值加权的
UMD_ret = f.groupby([ 'tradedate', 'group_UMD']).apply(lambda x:x.UMD.mean()) # 计算每年每月各组的动量因子  
UMD_ret = UMD_ret.reset_index()
UMD_ret = UMD_ret.rename(columns = {UMD_ret.columns[- 1]: 'ret'})
# 计算UMD因子
UMD_ret_pivot = UMD_ret.pivot(index = 'tradedate',columns = 'group_UMD',values = 'ret')
UMD = UMD_ret_pivot[ 'UMD_H'] - UMD_ret_pivot[ 'UMD_L']
# 最后再把UMD因子和fama三因子进行合并
Carhart4 = pd.concat([SMB,HML,UMD],axis = 1)
Carhart4 = Carhart4.reset_index()
Carhart4.columns = [ 'tradedate', 'SMB', 'HML', 'UMD']
Carhart4[ 'ym'] = Carhart4.tradedate.apply( lambda x:x.year* 100 + x.month)

(2)Carhat 四因子回归

# 四因子回归同三因子回归一样
## 定义解释变量
x = f25. loc[:,[ 'SMB', 'HML', 'UMD', 'mkt_rf', 'Intercept']]. values

## 设置存储指标的容器
r2 = []
betas = []
t = []
p = []
for i in range( 25):# i = 0
     y = f25. loc[:,f25.columns[i+ 1]]. values
     mod = sm.OLS( y, x).fit()

    r2. append([f25.columns[i+ 1], mod.rsquared])

    betas. append([f25.columns[i+ 1]] + list( mod.params))
    t. append([f25.columns[i+ 1]] + list( mod.tvalues))
     p. append([f25.columns[i+ 1]] + list( mod.pvalues))


## 存储指标 
p = pd.DataFrame( p,columns = [ 'group', 'SMB', 'HML', 'UMD', 'mkt_rf', 'Intercept'])
t = pd.DataFrame(t,columns = [ 'group', 'SMB', 'HML', 'UMD', 'mkt_rf', 'Intercept'])
betas = pd.DataFrame(betas,columns = [ 'group', 'SMB', 'UMD', 'HML', 'mkt_rf', 'Intercept'])

r2 = pd.DataFrame(r2,columns = [ 'group', 'r2'])

p_percent_car4 = ( p.iloc[:, 1:]< 0.05).mean()


alpha = betas[[ 'group', 'Intercept']]
alpha[ 'g_BM'] = alpha.group.apply(lambda x: x[ 2])
alpha[ 'g_SIZE'] = alpha.group.apply(lambda x: x[- 1])

alpha = alpha.pivot( index = 'g_SIZE',columns = 'g_BM', values = 'Intercept')
alpha = alpha.reset_index()

alpha = alpha. rename(columns = { 'g_SIZE': '',
                                    alpha.columns[ 1]: 'small BM',
                                    alpha.columns[- 1]: 'big BM'})
    

alpha.iloc[ 0, 0] = 'small SIZE'
alpha.iloc[- 1, 0] = 'big SIZE'
alpha
Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐