如何根据具有特定标识符的选定值(在该组行内)减去一组行

问题描述 投票:0回答:1

我不确定是否应该使用 groupby 、 idx 来解决这个问题,甚至采取额外的步骤将此数据帧变成多索引数据帧,但我希望该示例能够清楚地传达我遇到的问题。(下图为多索引形式)

我有一个如下所示的数据框(df),我想将每组剂量减去各自的空平均值,并将这些值放入名为“norm”的新列中。

Chem ID  Dose     average
A    23  Control  0.45
         Empty    0.33
         Positive 0.55
         1mM      0.66
B    24  Control  0.67
         Empty    0.45
         Positive 0.80
         1mM      0.70
C    26  Control  0.66
         Empty    0.50
         Positive 0.78
         1mM      0.66
D    29  Control  0.54
         Empty    0.24
         Positive 0.33
         1mM      0.78
E    30  Control  0.66
         Empty    0.40
         Positive 0.76
         1mM      0.56
F    35  Control  0.67
         Empty    0.32
         Positive 0.43
         1mM      0.44

这是所需的输出:

Chem ID  Dose     average norm
A    23  Control  0.45    0.12
         Empty    0.33    0.00
         Positive 0.55    0.22
         1mM      0.66    0.33
B    24  Control  0.67    0.22
         Empty    0.45    0.00
         Positive 0.80    0.35
         1mM      0.70    0.25
C    26  Control  0.66    0..16
         Empty    0.50    0.00
         Positive 0.78    0..28
         1mM      0.66    0.16
D    29  Control  0.54    0.30
         Empty    0.24    0.00
         Positive 0.33    0.09
         1mM      0.78    0.54
E    30  Control  0.66    0.26
         Empty    0.40    0.00
         Positive 0.76    0.36
         1mM      0.56    0.16
F    35  Control  0.67    0.35
         Empty    0.32    0.00
         Positive 0.43    0.11
         1mM      0.44    0.12

我一直在寻找类似的问题,并且仅通过使用 groupby 方法来接近减去最小值。然而,并非所有化学品都将 Empty 作为其最低值,因此 min 方法不起作用。我想以某种方式指定减去每个化学物质和 ID 各自的“空”。任何帮助将不胜感激!

df['norm']= df.groupby(['Chem','ID'])['average'].transform(lambda x: x- x.min())

python pandas dataframe series multi-index
1个回答
1
投票

你可以将索引设置为

['Chem','ID']
,通过
Dose='Empty'
进行过滤,然后进行自连接:

df = df.set_index(['Chem','ID'])
df_empty = df[df['Dose'] == 'Empty'].groupby(level=[0,1]).agg({'average':'mean'})
df2 = df.merge(df_empty, how='outer', left_index=True, right_index=True).rename(columns={'average_x':'average', 'average_y':'average_empty'})
df2['norm'] = df2['average'] - df2['average_empty']

结果:

>>> df2
             Dose  average  average_empty  norm
Chem ID                                        
A    23   Control     0.45           0.33  0.12
     23     Empty     0.33           0.33  0.00
     23  Positive     0.55           0.33  0.22
     23       1mM     0.66           0.33  0.33
B    24   Control     0.67           0.45  0.22
     24     Empty     0.45           0.45  0.00
     24  Positive     0.80           0.45  0.35
     24       1mM     0.70           0.45  0.25
C    26   Control     0.66           0.50  0.16
     26     Empty     0.50           0.50  0.00
     26  Positive     0.78           0.50  0.28
     26       1mM     0.66           0.50  0.16
D    29   Control     0.54           0.24  0.30
     29     Empty     0.24           0.24  0.00
     29  Positive     0.33           0.24  0.09
     29       1mM     0.78           0.24  0.54
E    30   Control     0.66           0.40  0.26
     30     Empty     0.40           0.40  0.00
     30  Positive     0.76           0.40  0.36
     30       1mM     0.56           0.40  0.16
F    35   Control     0.67           0.32  0.35
     35     Empty     0.32           0.32  0.00
     35  Positive     0.43           0.32  0.11
     35       1mM     0.44           0.32  0.12
© www.soinside.com 2019 - 2024. All rights reserved.