【问题标题】:Condition between duplicated values in a column列中重复值之间的条件
【发布时间】:2019-03-27 11:06:47
【问题描述】:

当每个客户有多个计划时,他们就会被重复。我想给客户设置状态:

如果他们每个产品都填写了“canceled_at”,则客户状态被取消,但当不是所有产品都填写了“cancelled_at”,而是至少有一个产品时,状态为“降级”,因为他丢失了一个产品。

customer|canceled_at|status
x       |3/27/2018  |
x       |           |
y       |2/2/2018   |
y       |2/2/2018   |
z       |1/1/2018   |
a       |           |      

我已经有取消状态,现在只需要降级

df['status']=(df.groupby('customer')['canceled_at'].
  transform(lambda x: x.notna().all()).map({True:'canceled'})).fillna(df.status)
customer|canceled_at|status
x       |3/27/2018  |downgrade
x       |           |downgrade
y       |2/2/2018   |canceled
y       |2/2/2018   |canceled
z       |1/1/2018   |canceled
a       |           |      

【问题讨论】:

    标签: python pandas pandas-groupby pandas-loc


    【解决方案1】:

    这里可以比较列是否没有缺失值,并按Series customerGroupBy.transformGroupBy.all 分组, GroupBy.any 用于测试所有值 Trues(所有未丢失)或至少一个未丢失值(任何未丢失)并将其传递给 numpy.select

    g = df['canceled_at'].notna().groupby(df['customer'])
    m1 = g.transform('all')
    m2 = g.transform('any')
    
    df['status'] = np.select([m1, m2],['canceled','downgrade'], np.nan)
    print (df)
      customer canceled_at     status
    0        x   3/27/2018  downgrade
    1        x         NaN  downgrade
    2        y    2/2/2018   canceled
    3        y    2/2/2018   canceled
    4        z    1/1/2018   canceled
    5        a         NaN        nan
    

    或者:

    df['status'] = np.select([m1, m2],['canceled','downgrade'], '')
    print (df)
      customer canceled_at     status
    0        x   3/27/2018  downgrade
    1        x         NaN  downgrade
    2        y    2/2/2018   canceled
    3        y    2/2/2018   canceled
    4        z    1/1/2018   canceled
    5        a         NaN         
    

    如果只有NaNs 组需要转换为downgrade

    mask = df['canceled_at'].notna().groupby(df['customer']).transform('all')
    df['status'] = np.where(mask,'canceled','downgrade')
    print (df)
      customer canceled_at     status
    0        x   3/27/2018  downgrade
    1        x         NaN  downgrade
    2        y    2/2/2018   canceled
    3        y    2/2/2018   canceled
    4        z    1/1/2018   canceled
    5        a         NaN  downgrade  
    

    【讨论】:

      【解决方案2】:

      这是一种方法:

      import pandas as pd
      
      def select_status(canceled):
          c = canceled.count()
          if c == 0:
              status = ''
          elif c == len(canceled):
              status = 'canceled'
          else:
              status = 'downgrade'
          return pd.Series(status, index=canceled.index)
      
      df = pd.DataFrame({'customer': ['x', 'x', 'y', 'y', 'z', 'a'],
                         'canceled_at': ['3/27/2018', None, '2/2/2018', '2/2/2018', '1/1/2018', None]})
      df['status'] = df.groupby('customer')['canceled_at'].apply(select_status)
      print(df)
      

      输出:

        customer canceled_at     status
      0        x   3/27/2018  downgrade
      1        x        None  downgrade
      2        y    2/2/2018   canceled
      3        y    2/2/2018   canceled
      4        z    1/1/2018   canceled
      5        a        None
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-03-09
        • 2015-09-08
        • 1970-01-01
        • 2013-06-01
        • 1970-01-01
        • 2021-05-09
        • 2018-03-25
        相关资源
        最近更新 更多