def cc_stats(x1, x2, demean=True):
 (nobs1, k1) = x1.shape
 (nobs2, k2) = x2.shape
 cc = cancorr(x1, x2, demean=demean)
 cc2 = (cc ** 2)
 lam = (cc2 / (1 - cc2))
 df_model = (k1 * k2)
 df_resid = (k1 * ((nobs1 - k2) - demean))
 s = min(df_model, k1)
 m = (0.5 * (df_model - k1))
 n = (0.5 * ((df_resid - k1) - 1))
 df1 = (k1 * df_model)
 df2 = k2
 pt_value = cc2.sum()
 wl_value = np.product((1 / (1 + lam)))
 ht_value = lam.sum()
 rm_value = lam.max()
 res = {}
 res['canonical correlation coefficient'] = cc
 res['eigenvalues'] = lam
 res["Pillai's Trace"] = pt_value
 res["Wilk's Lambda"] = wl_value
 res["Hotelling's Trace"] = ht_value
 res["Roy's Largest Root"] = rm_value
 res['df_resid'] = df_resid
 res['df_m'] = m
 return res

def cc_stats ( x1 , x2 , demean = True ) : ( nobs1 , k1 ) = x1 . shape ( nobs2 , k2 ) = x2 . shape cc = cancorr ( x1 , x2 , demean = demean ) cc2 = ( cc ** 2 ) lam = ( cc2 / ( 1 - cc2 ) ) df_model = ( k1 * k2 ) df_resid = ( k1 * ( ( nobs1 - k2 ) - demean ) ) s = min ( df_model , k1 ) m = ( 0.5 * ( df_model - k1 ) ) n = ( 0.5 * ( ( df_resid - k1 ) - 1 ) ) df1 = ( k1 * df_model ) df2 = k2 pt_value = cc2 . sum ( ) wl_value = np . product ( ( 1 / ( 1 + lam ) ) ) ht_value = lam . sum ( ) rm_value = lam . max ( ) res = { } res [ 'canonical correlation coefficient' ] = cc res [ 'eigenvalues' ] = lam res [ "Pillai's Trace" ] = pt_value res [ "Wilk's Lambda" ] = wl_value res [ "Hotelling's Trace" ] = ht_value res [ "Roy's Largest Root" ] = rm_value res [ 'df_resid' ] = df_resid res [ 'df_m' ] = m return res
manova statistics based on canonical correlation coefficient calculates pillais trace .