根据条件分配标志值

时间:2018-01-30 03:16:24

标签: python pandas dataframe

我的数据框如下所示

    groups|score|threshold|cumsum|
    A     |3    |4        |3     |
    A     |2    |4        |5     |
    A     |1    |4        |6     |
    B     |6    |5        |6     |
    B     |1    |5        |7     |
    C     |4    |4        |4     |

在Dataframe中,我想创建一个名为top_flag的新列。这个新专栏将把数据框中的观察结果标记为傻瓜;

  1. 将每个小于阈值的观察结果标记为1.在这种情况下,只会标记A组中的第一个观察结果。
  2. 2.接下来,在每个组中,将违反上述条件的第一行标记为1.这样,我们可以看到B组中的所有观察都违反了(1)中的条件,因此只会标记第一行在该组中观察为1,否则为0.对于C,只有一个观察并且它违反了我们的条件,但由于在该组中只有1个观察,我们将其标记为1无论如何。 我想要的最终数据集应如下所示:

        groups|score|threshold|cumsum|top_flag
        A     |3    |4        |3     |1
        A     |2    |4        |5     |0
        A     |1    |4        |6     |0
        B     |6    |5        |6     |1
        B     |1    |5        |7     |0
        C     |4    |4        |4     |1
    

    有人能告诉我如何轻松地做这个熊猫吗? 我的第一次尝试如下:

        #condition 1
        df1 =df[df.cumsum < df.threshhold]
        df['top_flag'] = 1
        #condition 2
        df2 = df[df.cum >= df.threshhold]
        #within each group rank cumsum in ascending to flag anywhere rank = 1 as 1 else 0.
        df2['rank'] =df2.groupby(['groups'])['cumsum'].apply(lambda x: x.rank())    
    
        df2['top_flag'] = df1['rank'].apply(lambda x: 1 if x == 1 else 0)
        df2 = df2.drop(columns = 'rank')
        df_final = pd.concat([df1,df22])
        df_final = df_final.groupby(['groups'])
    

    我强烈地感觉在熊猫中有一种更加光滑的方式。有谁知道更好的方法?

1 个答案:

答案 0 :(得分:0)

IIUC,对于第一个条件,进行简单的系列比较。对于第二个条件,请执行groupby + cumcount,并仅使用0行。或者获得top_flag的两个条件。

df['top_flag'] = (
      (df['threshold'] > df['cumsum']) | df.groupby('groups').cumcount().eq(0)
).astype(int)

df

  groups  score  threshold  cumsum  top_flag
0      A      3          4       3         1
1      A      2          4       5         0
2      A      1          4       6         0
3      B      6          5       6         1
4      B      1          5       7         0
5      C      4          4       4         1