根据单元格信息转换 pandas DataFrame

Transform pandas DataFrame based on cell information

我有一个 pd DataFrame df,格式如下:

model              auc            p             r
`a-num5-run1`      0.9            0.8           1.0
`a-num5-run2`      0.8            0.7           0.9
`b-num5-run1`      0.7            0.6           0.8
`b-num5-run2`      0.6            0.5           0.7
`a-num10-run1`     0.5            0.4           0.6
`a-num10-run2`     0.4            0.3           0.5
`b-num10-run1`     0.3            0.2           0.4
`b-num10-run2`     0.2            0.1           0.3
.... 
`a-num100-run1`     0.8            0.9           0.7
`a-num100-run2`     0.6            0.7           0.4
`a-num100-run1`     0.4            0.5           0.1
`a-num100-run2`     0.2            0.3           0.8

model栏显示了每个模型可以区分的维度。 现在,我想创建一个 DataFrame,其中每列的值在它们的运行中取平均值并存储在一个元组中,每个数字是一列,每一行是一个模型(在本例中为 a 或 b)。期望的结果将是如下所示的矩阵:

model_name     5                         10                   ...   100
a              (0.85, 0.75, 0.95)        (0.45, 0.35, 0.55)   ...   (0.7, 0.8, 0.55)
b              (0.65, 0.55, 0.75)        (0.25, 0.15, 0.35)   ...   (0.3, 0.4, 0.45)

我该怎么做?

首先通过 Series.str.split, then use DataFrame.pivot_table with extract integrers by Series.str.extract 将列拆分为助手 DataFrame,默认为 mean,最后创建元组:

df1 = df['model'].str.split('-', expand=True)

df = (df.pivot_table(index=df1[0], 
                    columns=df1[1].str.extract('(\d+)', expand=False).astype(int), 
                    values=['auc','p','r'], fill_value=0)
       .round(2)
       .T
       .groupby(level=1)
       .agg(tuple)
       .T)
print (df)
1                 5                   10               100
0                                                         
a  (0.85, 0.75, 0.95)  (0.45, 0.35, 0.55)  (0.5, 0.6, 0.5)
b  (0.65, 0.55, 0.75)  (0.25, 0.15, 0.35)  (0.0, 0.0, 0.0)

如果列的顺序未排序,请使用:

df = df.join(df[['auc','p','r']].add_suffix('_std'))
# print (df)

#not sorted ordering of columns
cols = ['p', 'p_std','auc', 'auc_std', 'r','r_std']

df1 = df['model'].str.split('-', expand=True)

df = (df.pivot_table(index=df1[0], 
                    columns=df1[1].str.extract('(\d+)', expand=False).astype(int), 
                    values=cols, fill_value=0)
       .round(2)
       .reindex(cols, axis=1, level=0)
       .T
       .groupby(level=1)
       .agg(tuple)
       .T)
print (df)
1                                   5                                     10   \
0                                                                               
a  (0.75, 0.75, 0.85, 0.85, 0.95, 0.95)  (0.35, 0.35, 0.45, 0.45, 0.55, 0.55)   
b  (0.55, 0.55, 0.65, 0.65, 0.75, 0.75)  (0.15, 0.15, 0.25, 0.25, 0.35, 0.35)   

1                             100  
0                                  
a  (0.6, 0.6, 0.5, 0.5, 0.5, 0.5)  
b  (0.0, 0.0, 0.0, 0.0, 0.0, 0.0)