У меня есть следующее pandas.DataFrame
match_id court
0 50311513 1
1 50313011 2
2 50313009 2
3 50317691 1
4 50315247 2
5 50318597 1
6 50318877 1
7 50318983 1
8 50318831 1
9 50318595 1
Как видите, всего курсов 2
. Я хочу объединить каждый «слот» вместе.
Итак, первый сгруппированный df должен содержать совпадение 50311513
и 50313011
. Второй слот должен содержать 50313009
и 50317691
. После третьего слота сгруппированный df по сути представляет собой одну строку.
Как я могу сказать pandas.groupby()
, что на поле можно сыграть только один матч?
Спасибо
Редактировать
Различные входные данные:
match_id court group
0 46768193 1 0
1 46768193 1 1
2 46768187 2 0
3 46768187 2 1
4 46767821 3 0
IIUC, вы можете сформировать две последовательные группы с общим количеством :
# start new group on identical values
g1 = df['court'].eq(df['court'].shift()).cumsum()
# in the previous groups, restart if the value was already seen
g2 = df['court'].groupby([df['court'], g1]).cumcount()
df['group'] = df.groupby([g1, g2]).ngroup()
# variant
# df['group'] = (g1.diff().ne(0)|g2.diff().ne(0)).cumsum().sub(1)
Выход:
match_id court group
0 50311513 1 0
1 50313011 2 0
2 50313009 2 1
3 50317691 1 1
4 50315247 2 2
5 50318597 1 2
6 50318877 1 3
7 50318983 1 4
8 50318831 1 5
9 50318595 1 6
Промежуточные продукты:
match_id court g1 g2 group
0 50311513 1 0 0 0
1 50313011 2 0 0 0
2 50313009 2 1 0 1
3 50317691 1 1 0 1
4 50315247 2 1 1 2
5 50318597 1 1 1 2
6 50318877 1 2 0 3
7 50318983 1 3 0 4
8 50318831 1 4 0 5
9 50318595 1 5 0 6
Если вам нужно обрабатывать больше групп, вы можете использовать пользовательскую (итеративную) функцию с набором для отслеживания уже просмотренных элементов. Если набор ранее просмотренных элементов уже содержит текущий элемент, создайте новую группу:
def grouper(s):
S = set()
group = []
n = 0
for val in s:
if val in S:
n += 1
S = {val}
else:
S.add(val)
group.append(n)
return group
df['group'] = grouper(df['court'])
Пример:
match_id court group
0 50311513 1 0
1 50313011 2 0
2 50313012 3 0
3 50313009 2 1
4 50317691 1 1
5 50315247 2 2
6 50315248 3 2
7 50318597 1 2
8 50318877 1 3
9 50318983 1 4
10 50319873 3 4
11 50318831 1 5
12 50318595 1 6
Заставил это работать, используя: def grouper(s: pd.Series) -> List[int]: groups = [] Courts = set(s.unique()) n = defaultdict(int, {c: 0 для c в судах} ) для v в s: n[v] += 1 groups.append(n[v]) return groups
@HJA24 мне кажется df.groupby('court').cumcount()
.
Я добавил еще один пример, где ваше предложение не работает. Есть идеи, как настроить ваше решение?