Группировка серии в Python

title edit: капитализация исправлена и добавлена "для python".

есть ли лучше или более стандартный способ сделать то, что я описываю? Мне нужен такой ввод:

[1, 1, 1, 0, 2, 2, 0, 2, 2, 0, 0, 3, 3, 0, 1, 1, 1, 1, 1, 2, 2, 2]

чтобы трансформироваться в это:

[0, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0]

или, еще лучше, что-то вроде этого (описывая аналогичный вывод по-разному, но теперь не ограничиваясь целыми числами):

метки: [1, 2, 3, 1, 2]

позиции(где 1 определил первое положение occupiable, как в моем библиотек matplotlib участка): [2, 7, 12.5, 17, 21]

входные данные-это категориальные данные, которые классифицировали участок - на рисунке ниже сгруппированные участки разделяют категориальную функцию, которую я хотел бы отметить только один раз для группы. Я буду использовать 2 оси для двух разных переменных, но я думаю, что это не имеет значения.

Примечание: это изображение не отражает ни один набор данных образца - это просто, чтобы получить через идею группировки вместе категорий. Группа а должно быть помечено при x=5, так как между первыми двумя и второй вертикальными группами данных есть пустое пространство, а 0-линия справа.

Image demonstrating placement of tick marks in the center of a category of data

вот что у меня получилось:

data = [1, 1, 1, 2, 2, 2, 2, 2, 3, 4, 3, 2, 2, 1, 1, 1, 1]
last = None
runs = []
labels = []
run = 1
for x in data:
    if x in (last, 0):
        run += 1
    else:
        runs.append(run)
        run = 1
        labels.append(x)
    last = x
runs.append(run)
runs.pop(0)
labels.append(x)
tick_positions = [0]
last_run = 1
for run in runs:
    tick_positions.append(run/2.0+last_run/2.0+tick_positions[-1])
    last_run = run
tick_positions.pop(0)
print tick_positions

1 ответов


чтобы получить метки, Вы можете использовать itertools groupby:

>>> import itertools
>>> numbers = [1, 1, 1, 0, 2, 2, 0, 2, 2, 0, 0, 3, 3, 0, 1, 1, 1, 1, 1, 2, 2, 2]
>>> list(k for k, g in itertools.groupby(numbers))
[1, 0, 2, 0, 2, 0, 3, 0, 1, 2]

и для удаления нулей вы можете использовать понимание:

>>> list(k for k, g in itertools.groupby(x for x in numbers if x != 0))
[1, 2, 3, 1, 2]

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