Ключом к успеху является правильная функция, генерирующая Tile
значений:
def tbl(x):
ccl = itertools.cycle([1,2,3])
lst = [ next(ccl) for _ in range(len(x)) ]
return pd.Series(lst, x.index)
Это работает почти как cumcount()
с одним отличием: вместо последовательных
числа (от range
) он генерирует циклическую последовательность [1,2,3]
,
используя itertools.cycle
.
Тогда все, что вам нужно сделать (после необходимого импорта и создания источника
DataFrame):
- Сортировать значения по
Animal
.
- Сгруппируйте по
Animal
, возьмите любой столбец (например, Name
) и примените к ним
вышеупомянутая функция.
Таким образом, весь сценарий (без объявления tbl
) может быть следующим:
import pandas as pd
import itertools
df = pd.DataFrame( {'Name': ['Harry', 'Sally', 'Mary', 'John', 'Francis',
'Devon', 'James', 'Holly', 'Molly', 'Nancy', 'Ben'],
'Score': [43, 234, 54, 34, 12, 43, 54, 65, 23, 12, 32],
'Animal': ['dog', 'dog', 'cat', 'cat', 'dog', 'horse', 'dog', 'snake',
'cat', 'mouse', 'mouse']})
df.sort_values(by='Animal', inplace=True)
df['Tile'] = df.groupby('Animal')['Name'].apply(tbl)
Когда вы печатаете df
, результат будет:
Name Score Animal Tile
2 Mary 54 cat 1
3 John 34 cat 2
8 Molly 23 cat 3
0 Harry 43 dog 1
1 Sally 234 dog 2
4 Francis 12 dog 3
6 James 54 dog 1
5 Devon 43 horse 1
9 Nancy 12 mouse 1
10 Ben 32 mouse 2
7 Holly 65 snake 1