У меня есть фрейм данных, который выглядит так
И я хотел бы получить результат, подобный следующему, где отдельным идентификаторам (которые строятся поверх комбинаций предыдущих столбцов) присваивается возрастающее целое число для каждого отдельного значения:
Извиняюсь за маленькое эссе. И спасибо за вашу помощь. Я попытался перебрать несколько групп, но я потерялся в нем.
С уважением, Дарио
Ага. Это не имеет никакого смысла. Поведение «-» в каждом из столбцов кажется совершенно разным.
Похоже на ошибку, столбец три, ряд 2,3,4 должен быть 2, а не 1
В столбце «Три», строка 1, «-» — это первый уникальный идентификатор, который имеет предыдущий путь (комбинацию) «А» и «-» в столбцах Один и Два соответственно. «C» в строке 2,3,4 также получает 1, потому что это первый идентификатор для комбинации «A» «B» в первом и втором столбцах.
Итак, если значение присутствует в той же строке в предыдущих столбцах, оно становится таким же, как если бы значение еще не возникло? Это не имеет никакого смысла. Я также не понимаю, почему тогда Б в «Два» получает 2. Глядя на это снова, кажется, что вы рассматриваете как предыдущие значения в ROW, так и COL, в котором находится значение. Итак, [2, Two] равно 2, потому что B является вторым уникальным значением в столбце 2 и не имеет присвоен идентификатор в столбце One. Это ваша логика?
Ни один столбец Шесть не состоит из единиц. Хорошо, я сдаюсь, извините, это выше моего понимания.
IIUC нужно последовательно выполнять groupby.ngroup, используя предыдущий столбец как группировщик:
out = pd.DataFrame(index=df.index)
out[df.columns[0]] = df.groupby(df.columns[0]).ngroup().add(1)
for i in range(1, df.shape[1]):
out[df.columns[i]] = (df
.groupby(df.columns[i-1], group_keys=False)
.apply(lambda g: g.groupby(df.columns[i]).ngroup().add(1)).squeeze()
)
print(out)
Если вам нужно сгруппировать по всем предыдущим столбцам, измените цикл на:
for i in range(1, df.shape[1]):
out[df.columns[i]] = (df
.groupby(list(df.columns[:i]), group_keys=False)
.apply(lambda g: g.groupby(df.columns[i]).ngroup().add(1)).squeeze()
)
Выход:
One Two Three Four Five Six
Index
1 1 1 1 1 1 1
2 1 2 1 1 1 1
3 1 2 1 2 1 1
4 1 2 1 2 2 1
5 1 2 2 1 1 1
6 1 2 2 2 1 1
7 1 2 2 3 1 1
8 1 2 3 1 1 1
9 1 2 3 2 1 1
Это все предыдущие столбцы. Я протестирую это завтра. Спасибо, приятель, ты настоящая легенда.
Дружище, действительно ценю это. У меня возник дополнительный вопрос. Результат не течет, но есть ли способ получить 0 (ноль) вместо 1, когда значения равны «-»? Все остальное должно выглядеть точно так же, та же логика, например. Второй столбец должен быть 0,1,1,1,1,1,1,1,1 и шестой столбец 0,0,0,1,0,0,1,0,1
Проще всего сохранить исходный код, замаскировав: out = out.mask(df.eq('-'), 0)
Это работает, приятель, я знаю, что для некоторых столбцов есть «2» без «1» в качестве уникального идентификатора, но, честно говоря, это работает. Еще раз спасибо, приятель.
Я не понимаю логики. Почему '-' и 'C' в столбце 'Three' получают один и тот же идентификатор 1?