如何计算熊猫行之间的条件变化百分比?

时间:2020-04-02 22:13:06

标签: python python-3.x pandas

这是我的数据框:

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

1 个答案:

答案 0 :(得分:2)

IIUC,您想将Amount的每一行用Subject==2除以AmountPeriod==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