Создание счетчика, который увеличивается, если значение в предыдущем столбце отличается? - PullRequest
1 голос
/ 02 апреля 2019

Я создаю столбец счетчика, который увеличивается только тогда, когда значения в (i-1) отличаются от значений в i.

Ниже приведены примеры данных:

user_id sc_id
1         100
1         100
1         101
1         100
2         100
2         105
3         105
3         105

Нижемой код:

df['subcat_counter'] = 1

for i in range(1,len(df)):
    if df.sc_id[i-1]==df.sc_id[i] and df['user_id'][i-1]==df['user_id'][i]:
        df.at[i,'subcat_counter']=df.subcat_counter[i-1]
    else:
        df.at[i,'subcat_counter']=df.subcat_counter[i-1]+1

Ниже приведен обязательный вывод:

user_id sc_id   subcat_counter
1         100    1
1         100    1
1         101    2
1 .       100    3
2         100    4
2         105    5
3         105    6
3         105    6

Ошибка:

KeyError: 0

Ответы [ 2 ]

4 голосов
/ 02 апреля 2019

Использование GroupBy.ngroup:

df1 = df[['user_id','sc_id']].ne(df[['user_id','sc_id']].shift()).cumsum().add_prefix('g_')

df['subcat_counter'] = df.join(df1).groupby(['g_user_id','g_sc_id'], sort=False).ngroup() + 1
print (df)
   user_id  sc_id  subcat_counter
0        1    100               1
1        1    100               1
2        1    101               2
3        1    100               3
4        2    100               4
5        2    105               5
6        3    105               6
7        3    105               6

Другое решение:

s = df['user_id'].astype(str) + '_' + df['sc_id'].astype(str) 
df['subcat_counter'] = s.ne(s.shift()).cumsum()
print (df)

   user_id  sc_id  subcat_counter
0        1    100               1
1        1    100               1
2        1    101               2
3        1    100               3
4        2    100               4
5        2    105               5
6        3    105               6
7        3    105               6
1 голос
/ 02 апреля 2019

, если вас интересует только предыдущая строка, вы можете использовать .shift(), чтобы получить ее значения, а затем сделать соответствующие сравнения. Здесь мы проверяем, совпадают ли user_id и sc_id с предыдущей строкой, и отменяем ее, чтобы найти точки, где мы хотим, чтобы наше значение изменилось. Затем мы конвертируем его в int, чтобы получить True как 1 и False как 0 (это не является строго необходимым, но помогает объяснить, что происходит), а затем делаем накопительную сумму.

prev_row = df.shift(1)

df['subcat_counter'] = (
    ~(df['user_id'].eq(prev_row['user_id']) & df['sc_id'].eq(prev_row['sc_id']))
).astype(int).cumsum()
...