Панды Подать заявку с условием - PullRequest
2 голосов
/ 19 марта 2019

У меня есть дубликаты клиентов с различным статусом, потому что для каждой подписки / продукта клиента есть строка.Я хочу сгенерировать new_status для клиента и для его «отмены», каждый статус подписки должен быть «отменен» вместе.

Я использовал:

df['duplicated'] = df.groupby('customer', as_index=False)['customer'].cumcount()

для разделениякаждый дублируется в индексе для указания дублированных значений

Customer | Status | new_status | duplicated
 X       |canceled|            | 0
 X       |canceled|            | 1
 X       |active  |            | 2
 Y       |canceled|            | 0
 A       |canceled|            | 0
 A       |canceled|            | 1
 B       |active  |            | 0
 B       |canceled|            | 1

Таким образом, я хотел бы использовать .apply и / или .loc для генерации:

Customer | Status | new_status | duplicated
 X       |canceled|            | 0
 X       |canceled|            | 1
 X       |active  |            | 2
 Y       |canceled|            | 0
 A       |canceled| canceled   | 0
 A       |canceled| canceled   | 1
 B       |active  |            | 0
 B       |canceled|            | 1

Ответы [ 2 ]

2 голосов
/ 19 марта 2019

Сравните столбец по Series.eq для == и используйте GroupBy.transform с GroupBy.all для проверки, все ли значения True сдля групп, затем сравните Customer с Series.duplicated с keep=False для возврата всех дупликов.Последняя цепочка вместе поразрядно AND (&) и устанавливает значения по numpy.where:

m1 = df['Status'].eq('canceled').groupby(df['Customer']).transform('all')
m2 = df['Customer'].duplicated(keep=False)

df['new_status'] = np.where(m1 & m2, 'cancelled', '')
print (df)
  Customer    Status new_status  duplicated
0        X  canceled                      0
1        X  canceled                      1
2        X    active                      2
3        Y  canceled                      0
4        A  canceled  cancelled           0
5        A  canceled  cancelled           1
6        B    active                      0
7        B  canceled                      1
1 голос
/ 19 марта 2019

Насколько я понимаю, вы можете попытаться сделать:

df['new_status']=(df.groupby('Customer')['Status'].
  transform(lambda x: x.eq('canceled').all()).map({True:'cancelled'})).fillna(df.new_status)
print(df)

    Customer    Status new_status  duplicated
0   X         canceled             0         
1   X         canceled             1         
2   X         active               2         
3   Y         canceled  cancelled  0         
4   A         canceled  cancelled  0         
5   A         canceled  cancelled  1         
6   B         active               0         
7   B         canceled             1   

РЕДАКТИРОВАТЬ, так как ожидаемое значение o / p было изменено:

df['new_status']=(df.groupby('Customer')['Status'].
             transform(lambda x: x.duplicated(keep=False)&(x.eq('canceled').all()))
                         .map({True:'cancelled',False:''}))
print(df)

  Customer    Status new_status  duplicated
0   X         canceled             0         
1   X         canceled             1         
2   X         active               2         
3   Y         canceled             0         
4   A         canceled  cancelled  0         
5   A         canceled  cancelled  1         
6   B         active               0         
7   B         canceled             1   
...