Добавить условный счетчик: счетчик столбцов на основе значений других столбцов

#python #pandas

#python #pandas

Вопрос:

У меня есть такая таблица

 id    id2      val
a     red      apple
a     red      orange
b     blue     fish
c     violet   beef
a     yellow   banana
a     black    pork
 

Я хочу создать счетчик на основе значений id и id2.

Например, id — это идентификатор клиента, id2 — идентификатор заказа, а val — имя элемента в заказе. Я хочу создать счетчик для идентификатора клиента и идентификатора заказа. Вот почему первые 2 строки должны иметь одинаковый счетчик 1

Я попробовал cumcount, но они дадут мне что-то вроде этого

 id    id2      val      counter
a     red      apple    1
a     red      orange   2
b     blue     fish     1
c     violet   beef     1
a     yellow   banana   1
a     black    pork     1
 

Я попробовал cumcount

df['counter'] = df.groupby(['id','id2']).cumcount() 1

но это не то, что я хочу

Мне нужна таблица результатов, подобная этой

 id    id2      val      counter
a     red      apple    1
a     red      orange   1
b     blue     fish     1
c     violet   beef     1
a     yellow   banana   2
a     black    pork     3
 

Спасибо,

Комментарии:

1. Я не слежу за ожидаемым результатом. Почему должно yellow banana быть 2, но violet beef только 1?

2. Это счетчик внутри id для каждого уникального значения id2 .

3. @roganjosh извините за неясность. Я только что добавил еще немного информации. например. id — это идентификатор клиента, id2 — идентификатор заказа, а val — идентификатор товара в заказе. как корзина в вашем заказе на Amazon. Я хочу создать счетчик количества заказов на одного клиента.

Ответ №1:

Похоже, вы пытаетесь подсчитать уникальные значения пар (id, id2) :

 uniques = df.drop_duplicates(subset=['id','id2']).groupby('id').cumcount() 1
df['counter'] = uniques.reindex(df.index).ffill().astype(int)
 

Комментарии:

1. Привет, это именно то, что мне нужно. Большое спасибо!

Ответ №2:

Вы можете использовать groupby.transform и pandas.factorize :

 df['counter'] = df.groupby(['id'])['id2'].transform(lambda x: pd.factorize(x)[0]).add(1)

  id     id2     val  counter
0  a     red   apple        1
1  a     red  orange        1
2  b    blue    fish        1
3  c  violet    beef        1
4  a  yellow  banana        2
5  a   black    pork        3
 

Комментарии:

1. можете ли вы объяснить, как pd.factorize(x)[0] это работает. Спасибо

2. конечно, это кодировщик меток категорий… он кодирует каждую уникальную категорию как целое число, начиная с 0 , поэтому в первом id «a» категория «red» будет кодироваться 0 , категория «yellow» будет кодироваться 1 и так далее. Следовательно, необходимо использовать .add(1) для желаемого результата. Поскольку мы используем его в groupby первой наблюдаемой категории в каждом id , она будет закодирована в 0