首页 > 解决方案 > 在 pandas 中使用基于多个特定条件的 for 循环计算多个列

问题描述

我有一个如下所示的数据框。

 B_ID   No_Show   Session  slot_num   Patient_count
    1     0.2       S1        1          1
    2     0.3       S1        2          1
    3     0.8       S1        3          1
    4     0.3       S1        3          2
    5     0.6       S1        4          1
    6     0.8       S1        5          1
    7     0.9       S1        5          2
    8     0.4       S1        5          3
    9     0.6       S1        5          4
    12    0.9       S2        1          1
    13    0.5       S2        1          2
    14    0.3       S2        2          1
    15    0.7       S2        3          1
    20    0.7       S2        4          1
    16    0.6       S2        5          1
    17    0.8       S2        5          2
    19    0.3       S2        5          3

在哪里

No_Show = 没有出现的概率

假使,假设

p = [0.2, 0.4] 并且每个时隙的持续时间 = 30(分钟)

p = 阈值概率

从上面我想计算下面的数据框

步骤1

根据 Session、slot_number 和 Patient_count 对数据帧进行排序

df = df.sort_values(['Session', 'slot_num', 'Patient_count'], ascending=False)

步骤 2 使用以下条件计算截止值

if patient_count = 1 将 No_show 除以阈值概率 if patient_count = 1

Example for B_ID = 3, Patient_count = 1, cut_off = 0.8/0.2 = 4

否则,如果 patient_count = 2 之前将 1 No_Show 与当前 No_show 相乘并除以阈值)

Example for B_ID = 4, Patient_count = 2, cut_off = (0.3*0.8)/0.2 = 1.2

else if patient_count = 3 之前将 2 No_Show 与当前 No_show 相乘并除以阈值

Example for B_ID = 8, Patient_count = 3, cut_off = (0.4*0.9*0.8)/0.2 = 1.44

等等

预期输出:

B_ID   No_Show   Session  slot_num   Patient_count Cut_off_0.2   Cut_off_0.4
    1     0.2       S1        1          1             1             0.5
    2     0.3       S1        2          1             1.5           0.75
    3     0.8       S1        3          1             4              2
    4     0.3       S1        3          2             1.2            0.6
    5     0.6       S1        4          1             3              1.5
    6     0.8       S1        5          1             4              2
    7     0.9       S1        5          2             3.6            1.8
    8     0.4       S1        5          3             1.44           0.72
    9     0.6       S1        5          4             0.864          0.432
    12    0.9       S2        1          1             4.5            2.25
    13    0.5       S2        1          2             2.25           1.125
    14    0.3       S2        2          1             1.5            0.75
    15    0.7       S2        3          1             3.5            1.75
    20    0.7       S2        4          1             3.5            1.75
    16    0.6       S2        5          1             3              1.5
    17    0.8       S2        5          2             2.4            1.2
    19    0.3       S2        5          3             0.72           0.36

我试过下面的代码

p = [0.2, 0.4]
for i in p:
    df['Cut_off_'+'i'] = df.groupby(['Session','slot_num'])['No_Show'].cumprod().div(i)

标签: pandaspandas-groupby

解决方案


您的解决方案可以在这里使用f-strings with{i}用于新列名称:

p = [0.2, 0.4]
for i in p:
    df[f'Cut_off_{i}'] = df.groupby(['Session','slot_num'])['No_Show'].cumprod().div(i)

使用 numpy 的解决方案也是可能的 - 输出转换为 numpy 数组并除以p,然后转换DataFrame为原始数据并加入。

p = [0.2, 0.4]
arr = df.groupby(['Session','slot_num'])['No_Show'].cumprod().values[:, None] / np.array(p)

df = df.join(pd.DataFrame(arr, columns=p, index=df.index).add_prefix('Cut_off_'))

推荐阅读