这是我的数据框:
df = pd.DataFrame({'Period': ['1_Baseline', '1_Baseline', '1_Baseline', '2_Acute', '2_Acute', '2_Acute', '3_Chronic', '3_Chronic', '3_Chronic', '4_Discontinuation', '4_Discontinuation', '4_Discontinuation'],
'Subject': [1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3],
'Amount': [24, 52, 34, 95, 98, 54, 32, 20, 16, 52, 34, 95]})
我想创建一个列,其中包含每个期间相对于基准的每个主题内金额变化的百分比。因此,对于“基线”,它将显示主题1的金额从“基线”变为“急性”,从1_Baseline变为3_Chronic,从1_Baseline变为4_Discontinuation。每个主题都会做同样的事情。
这是我尝试过的:
df['pct_change'] = df.groupby(['Period'])['Amount'].pct_change()
但是我得到了
Period Subject Amount pct_change
0 1_Baseline 1 24 NaN
1 1_Baseline 2 52 1.166667
2 1_Baseline 3 34 -0.346154
3 2_Acute 1 95 1.794118
4 2_Acute 2 98 0.031579
5 2_Acute 3 54 -0.448980
6 3_Chronic 1 32 -0.407407
7 3_Chronic 2 20 -0.375000
8 3_Chronic 3 16 -0.200000
9 4_Discontinuation 1 52 2.250000
10 4_Discontinuation 2 34 -0.346154
11 4_Discontinuation 3 95 1.794118
不是在每个期间内计算结果,也不是相对于每个受试者以前的金额。
预期输出:
Period Subject Amount pct_change
0 1_Baseline 1 24 NaN
1 1_Baseline 2 52 NaN
2 1_Baseline 3 34 NaN
3 2_Acute 1 95 2.958333333
4 2_Acute 2 98 0.884615385
5 2_Acute 3 54 0.588235294
6 3_Chronic 1 32 0.333333333
7 3_Chronic 2 20 -0.615384615
8 3_Chronic 3 16 -0.529411765
9 4_Discontinuation 1 52 1.166666667
10 4_Discontinuation 2 34 -0.346153846
11 4_Discontinuation 3 95 1.794117647
答案 0 :(得分:2)
IIUC,您想将Amount
的每一行用Subject==2
除以Amount
和Period==1_Baseline
的{{1}}。这是我的方法:
Subject==2
输出:
s = df.set_index(['Subject', 'Period']).Amount.unstack('Period')
df['pct_change'] = (s.div(s['1_Baseline'], axis='rows').sub(1)
.unstack().values
)
请注意,行的顺序非常重要。在这种情况下,您确实具有正确的行顺序才能起作用。如果您不确定订单,那么合并会更安全:
Period Subject Amount pct_change
0 1_Baseline 1 24 0.000000
1 1_Baseline 2 52 0.000000
2 1_Baseline 3 34 0.000000
3 2_Acute 1 95 2.958333
4 2_Acute 2 98 0.884615
5 2_Acute 3 54 0.588235
6 3_Chronic 1 32 0.333333
7 3_Chronic 2 20 -0.615385
8 3_Chronic 3 16 -0.529412
9 4_Discontinuation 1 52 1.166667
10 4_Discontinuation 2 34 -0.346154
11 4_Discontinuation 3 95 1.794118