У меня есть фрейм данных, например:
a | b | c
a 1 2
b 1 3
c 1 1
d 2 2
e 2 3
f 2 1
Я хотел бы перетасовать строки, чтобы уменьшить количество последовательных дубликатов в B, поместив их в последовательном порядке в C, насколько это возможно. Фрейм данных может иметь сотни строк.
Желаемый результат для кадра данных выше может выглядеть так:
a | b | c
c 1 1
f 2 1
a 1 2
d 2 2
b 1 3
e 2 3
В столбце B нет последовательных дубликатов, а C находится в максимально возможной последовательности на основе строк в фрейме данных. C может принимать значения от 1 до 5, а B может принимать множество разных значений.
Если критерии больше не могут быть выполнены, а в фрейме данных все еще есть строки, можно поместить строку (строки) в любом месте фрейма данных (если это проще).
до сих пор мне был показан способ убедиться, что последовательные значения не встречаются в B:
np.random.seed(0)
(df.groupby(df.groupby('B').cumcount(), group_keys=False)
.apply(lambda x: x.sample(frac=1))
.reset_index(drop=True))
Но мне трудно заставить его включить последовательность столбца C в код.
Заранее спасибо!
@ cs95 круто, я не видел ни этого вопроса, ни твоего ответа! Да, это интересная задача, но не такая простая. Я предполагаю, что идеальным ответом был бы алгоритм «несортировки», который находит конфигурацию с максимальной энтропией значений b в каждой группе c.






Сортировки по c, а затем по b достаточно для вашего примера DataFrame, но он начнет ломаться, как только b примет повторяющиеся значения для заданного значения c:
df.sort_values(by=['c', 'b'])
a b c
2 c 1 1
5 f 2 1
0 a 1 2
3 d 2 2
1 b 1 3
4 e 2 3
@WeNYoBen, это решение не является самым общим подходом, но оно точно воспроизводит ожидаемый результат, указанный в вопросе.
Результат показанного вам метода зависит от случайного начального числа; в вашем случае просто удается избежать последовательных значений в столбце
b, но это изменится, если вы повторно запустите с другим начальным значением.