python 中的条件统计摘要数据框

Conditional statistic summary dataframe in python

我正在尝试获取 table 的 AB 的统计数据(均值、var、标准差等)给定 Y=1Y=0. 例如:

鉴于此数据框:

df = pd.DataFrame({'A': [0,    0.91, np.NaN, 0.75,   np.NaN, 1], 
                   'B': [0.43, 1,    0.34,   np.NaN, 0,      0.64],
                   'Y': [1,    0,    1,      1,      0,      1]
                      })

我正在计算统计数据:

for i in df:
    print(i)
    print("Mean Y1 " + " " + str(df[i][df["Y"]==1].mean()))
    print("Mean Y0 " + " " + str(df[i][df["Y"]==0].mean()))
    print("Var Y1 " + " " + str(np.var(df[i][df["Y"]==1])))
    print("Var Y0 " + " " + str(np.var(df[i][df["Y"]==0])))

但是,我无法比较它们,所以我尝试创建一个 table 统计数据,如下所示:

stats = pd.DataFrame({'Column names': ['A', 'B', 'Y']
                   'Mean Y1': [A_mean_given_Y==1, B_mean_given_Y==1, Z], 
                   'Mean Y0': [A_mean_given_Y==0, B_mean_given_Y==0, Z],
                   'Var Y1': [A_var_given_Y==1,   B_var_given_Y==1,  Z],
                   'Var Y0': [A_var_given_Y==0,   B_var_given_Y==0,  Z] 
                  })

# NOTE: Z is any number, as its value doesn't matter.

但是,df 不接受函数 .append,因为它用于列表。并在计算统计数据后转换数据框中的列表列表,效率非常低。那么,知道如何使用循环创建统计数据框吗?

我认为首先需要DataFrameGroupBy.agg by list of functions for aggregate and then flatten MultiIndex, also if need reshape add stack or unstack:

df1 = df.groupby('Y').agg(['mean','var'])
df1.columns = df1.columns.map('_'.join)
print (df1)
     A_mean     A_var  B_mean   B_var
Y                                    
0  0.910000       NaN    0.50  0.5000
1  0.583333  0.270833    0.47  0.0237

或:

df1 = df.groupby('Y').agg(['mean','var']).stack().sort_index(level=1)
df1.index = ['{}_{}'.format(j, i) for i, j in df1.index]
print (df1)
               A       B
mean_0  0.910000  0.5000
mean_1  0.583333  0.4700
var_0        NaN  0.5000
var_1   0.270833  0.0237

或:

df1 = df.groupby('Y').agg(['mean','var']).stack(0).unstack(0)
df1.columns = ['{}_{}'.format(i,j) for i, j in df1.columns]
print (df1)
   mean_0    mean_1  var_0     var_1
A    0.91  0.583333    NaN  0.270833
B    0.50  0.470000    0.5  0.023700

对于 Series 输出:

s = df.groupby('Y').agg(['mean','var']).unstack()
s.index = ['{}_{}_{}'.format(i,j,k) for i, j,k in s.index]
print (s)
A_mean_0    0.910000
A_mean_1    0.583333
A_var_0          NaN
A_var_1     0.270833
B_mean_0    0.500000
B_mean_1    0.470000
B_var_0     0.500000
B_var_1     0.023700
dtype: float64

考虑到它的灵活性,我最后这样做了(例如,您不受 agg 函数的限制,您可以将任何函数放在 table 中,只需将其添加到循环中):

 df = pd.DataFrame({'A': [0,    0.91, np.NaN, 0.75,   np.NaN, 1], 
                   'B': [0.43, 1,    0.34,   np.NaN, 0,      0.64],
                   'Y': [1,    0,    1,      1,      0,      1]
                      })   
stats = []
for i in df:
    new_row = [
        i,
        df[i][df["Y"]==1].mean(),
        df[i][df["Y"]==0].mean(),
        np.nanvar(df[i][df["Y"]==1]),
        np.nanvar(df[i][df["Y"]==0]),
    ]
    stats.append(new_row)

col_stats= ['Variable', 'Mean Y=1', 'Mean Y=0', 'Var Y=1', 'Var Y=0']
stats = pd.DataFrame(stats, columns=col_stats)
stats