Верните id группы в панд dataframe

Для dataframe

In [2]: df = pd.DataFrame({'Name': ['foo', 'bar'] * 3,
   ...:                    'Rank': np.random.randint(0,3,6),
   ...:                    'Val': np.random.rand(6)})
   ...: df
Out[2]: 
  Name  Rank       Val
0  foo     0  0.299397
1  bar     0  0.909228
2  foo     0  0.517700
3  bar     0  0.929863
4  foo     1  0.209324
5  bar     2  0.381515

Я интересуюсь группировкой по имени и Разрядом и возможно получением итоговых значений

In [3]: group = df.groupby(['Name', 'Rank'])
In [4]: agg = group.agg(sum)
In [5]: agg
Out[5]: 
                Val
Name Rank          
bar  0     1.839091
     2     0.381515
foo  0     0.817097
     1     0.209324

Но я хотел бы получить область в оригинале df , который содержит число группы для того ряда, как

In [13]: df['Group_id'] = [2, 0, 2, 0, 3, 1]
In [14]: df
Out[14]: 
  Name  Rank       Val  Group_id
0  foo     0  0.299397         2
1  bar     0  0.909228         0
2  foo     0  0.517700         2
3  bar     0  0.929863         0
4  foo     1  0.209324         3
5  bar     2  0.381515         1

Есть ли хороший способ сделать это у панд?

Я могу получить его с питоном,

In [16]: from itertools import count
In [17]: c = count()
In [22]: group.transform(lambda x: c.next())
Out[22]: 
   Val
0    2
1    0
2    2
3    0
4    3
5    1

но это довольно медленно на большом dataframe, таким образом, я полагал, что может быть более крепкое у панд способ сделать это.

16
nl ja de

1 ответы

Много удобных вещей сохранено в DataFrameGroupBy.grouper объект. Например:

>>> df = pd.DataFrame({'Name': ['foo', 'bar'] * 3,
                   'Rank': np.random.randint(0,3,6),
                   'Val': np.random.rand(6)})
>>> grouped = df.groupby(["Name", "Rank"])
>>> grouped.grouper.
grouped.grouper.agg_series        grouped.grouper.indices
grouped.grouper.aggregate         grouped.grouper.labels
grouped.grouper.apply             grouped.grouper.levels
grouped.grouper.axis              grouped.grouper.names
grouped.grouper.compressed        grouped.grouper.ngroups
grouped.grouper.get_group_levels  grouped.grouper.nkeys
grouped.grouper.get_iterator      grouped.grouper.result_index
grouped.grouper.group_info        grouped.grouper.shape
grouped.grouper.group_keys        grouped.grouper.size
grouped.grouper.groupings         grouped.grouper.sort
grouped.grouper.groups            

и так:

>>> df["GroupId"] = df.groupby(["Name", "Rank"]).grouper.group_info[0]
>>> df
  Name  Rank       Val  GroupId
0  foo     0  0.302482        2
1  bar     0  0.375193        0
2  foo     2  0.965763        4
3  bar     2  0.166417        1
4  foo     1  0.495124        3
5  bar     2  0.728776        1

Может быть более хороший псевдоним для для морской окунь group_info [0] скрывающийся вокруг где-нибудь, но это должно работать, так или иначе.

25
добавлено
Другой псевдоним, кажется, grouped.grouper.labels [0]
добавлено автор beardc, источник
@jflournoy: в странном совпадении у меня есть PR прямо сейчас, который уступил бы каноническому дорогу, чтобы получить доступ к этой информации.
добавлено автор DSM, источник
Три года спустя и эта вещь все еще не документирована. Но it' s легкий выяснить тот df.grouper имеет класс BaseGrouper . group_info метод определяется здесь в коде, и можно следовать за следом назад немного далее, чтобы подтвердить следующее: 1) , group_info[1] является множеством уникальных идентификаторов группы, 2) идентификатор группы для ряда я , group_info [0] [я] , и 3) , group_info[3] является количеством групп
добавлено автор shadowtalker, источник
только проблема - морской окунь, не зарегистрирован, никакая гарантия, которую это не сломает.
добавлено автор dashesy, источник
Возможно, это - моя наивность питона, но I' m удивил there' s не прямой, зарегистрированный метод. Я пришел к этому вопросу, потому что я хочу использовать sklearn.cross_validation. StratifiedShuffleSplit и наслаивайтесь через уникальные компании нескольких различных колонок. Этот ID группы - точно отдельный столбец, в котором я нуждаюсь для работы, но it' s жесткий, чтобы найти. I' d очень быть интересно знать, является ли это неправильным употреблением панд.
добавлено автор jflournoy, источник
Python
Python
7 654 участник(ов)

Уютный чат для профессионалов, занимающихся поиском питоньих мудростей. Как не получить бан: https://t.me/ru_python/577926

Python beginners
Python beginners
4 449 участник(ов)

Вопросы про Python для чайников. Cпам и троллинг неприемлем. Не злоупотребляйте стикерами. Частозадаваемые вопросы: https://github.com/ru-python-beginners/faq/blob/master/README.md Статистика тут: https://grstats.me/chat/x4qym2k5uvfkr3al6at7

pro.python
pro.python
1 090 участник(ов)

Сообщество разработчиков под Python Создатель: @rodgelius

Rude Python
Rude Python
971 участник(ов)

Python без „девочек”, здесь матерятся и унижают Django. Not gay friendly. Правила: t.me/rudepython/114107 @rudepython | t.me/rudepython

rupython
rupython
509 участник(ов)

Группа создана с целью оперативного получения ответов на возникающие вопросы по разработке на яп python, смежные темы, а также человеческого общения. Приветствую!

Python-programming
Python-programming
266 участник(ов)

Чат группы вконтакте https://vk.com/python_community