Сгруппируйте и подсчитайте только, сколько раз клиенту звонили в определенный момент времени.

моя проблема тесно связана с Групповой подсчет только тогда, когда определенное значение присутствует в одном из столбцов в pandas.

Допустим, у меня есть фрейм данных, отсортированный по not_unique_id и date_of_call.

rng = pd.date_range('2015-02-24', periods=8, freq='D')
df = pd.DataFrame(
    {
    "unique_id": ["K0", "K1", "K2", "K3", "K4", "K5", "K6","K7"],
    "not_unique_id": ["A000", "A111", "A222", "A222", "A222", "A222", "A222","A333"],
    "date_of_call": rng,
    "customer_reached": [1,0,0,1,1,1,1,1],
    }
    ) 
df.sort_values(['not_unique_id','date_of_call'], inplace=True, ascending=False)
df.reset_index(drop=True, inplace=True) # reset index

df.head(10)

введите здесь описание изображения

Теперь я хочу добавить новый столбец, который сообщает мне, как часто клиенту звонили успешно в прошлом. Другими словами: подсчитайте, сколько раз клиент был достигнут в прошлом, и сохраните результат в новом столбце. Для приведенного примера это будет результат:

введите здесь описание изображения

Как бы вы это сделали?


person PParker    schedule 19.03.2021    source источник


Ответы (1)


Если все даты и время уникальны и отсортированы, вы можете изменить порядок, сначала проиндексировав, а затем агрегировав пользовательскую функцию с shift и кумулятивной суммой с помощью Series.cumsum, в последнюю очередь замените отсутствующие значения и преобразуйте столбец в целые числа:

df['new'] = (df.iloc[::-1]
               .groupby('not_unique_id')['customer_reached']
               .apply(lambda x: x.shift().cumsum())
               .fillna(0)
               .astype(int))
print (df)
  unique_id not_unique_id date_of_call  customer_reached  new
0        K7          A333   2015-03-03                 1    0
1        K6          A222   2015-03-02                 1    3
2        K5          A222   2015-03-01                 1    2
3        K4          A222   2015-02-28                 1    1
4        K3          A222   2015-02-27                 1    0
5        K2          A222   2015-02-26                 0    0
6        K1          A111   2015-02-25                 0    0
7        K0          A000   2015-02-24                 1    0

Или, если возможно, изменить порядок:

df.sort_values(['not_unique_id','date_of_call'], inplace=True)


df['new'] = (df.groupby('not_unique_id')['customer_reached']
               .apply(lambda x: x.shift().cumsum())
               .fillna(0)
               .astype(int))
print (df)
  unique_id not_unique_id date_of_call  customer_reached  new
0        K0          A000   2015-02-24                 1    0
1        K1          A111   2015-02-25                 0    0
2        K2          A222   2015-02-26                 0    0
3        K3          A222   2015-02-27                 1    0
4        K4          A222   2015-02-28                 1    1
5        K5          A222   2015-03-01                 1    2
6        K6          A222   2015-03-02                 1    3
7        K7          A333   2015-03-03                 1    0
person jezrael    schedule 19.03.2021
comment
Большое спасибо за твою помощь! - person PParker; 19.03.2021