Итерация по кадрам данных pandas с сохранением памяти о предыдущих состояниях - PullRequest
0 голосов
/ 20 сентября 2018

Ниже приводится датафрейм, который у меня есть.JourneyGroup - мой ожидаемый столбец.

    Day  Journey  InitialValue  Value  JourneyGroup
0    12        1           3.0      4             1
1    12        1           4.0      5             1
2    12        0           NaN      7             1
3    12        0           NaN      2             1
4    12        1           5.0      8             2
5    12        0           NaN      9             2
6    13        1           3.0      4             3
7    13        1           4.0      5             3
8    13        0           NaN      7             3
9    13        0           NaN      6             3
10   13        1           1.0      2             3
11   13        0           NaN      9             0

Если Journey == 1, это указывает на начало путешествия.Пока Journey включен, другие Journey не могут начинаться с того же Day в последующих строках.Journey закончится, если текущая строка Value < InitialValue(from the first row of a journey).Как только начало и конец определены для Journey, назначается номер группы в JourneyGroup, сгруппированный в Day.

Например, в первом ряду Journey ==1, затем начинается Journey.Во втором ряду это также Journey==1, но Journey уже включен из первого ряда, поэтому, начиная со 2-го ряда, это просто продолжение первого Journey из 1-го ряда.В 4-й строке присваивается Value of 2 < InitialValue of 3, который обозначает конец Journey и JourneyGroup из 1.

Я могу использовать ngroup или pd.categorical, чтобы назначать группы и проверять условия, выполняя что-то вроде: df.Value<df.groupby(['Group??']).InitialValue.transform('first'), но не уверен, как итеративно составлять концепции, сохраняя память о том, является ли JourneyВКЛ или ВЫКЛ.

Примечание: - Journey не может занимать несколько дней и должен заканчиваться в тот же день, как и Journey2, даже если Value всегда было больше, чем InitialValue.

1 Ответ

0 голосов
/ 20 сентября 2018

Вот одна попытка, необходимо проверить больше данных:

t_num = ((df['Value'].shift() < df.groupby(['Day',df.groupby('Day')['Journey'].cummax()])['Value'].transform('first')) | df['Day'].diff().bfill().ne(0)).cumsum() + 1
m = t_num.diff().bfill().eq(1) & df.Journey.eq(0)
t_num = t_num.mask(m,0)
df['JGroup'] = t_num
df

Вывод:

    Day  Journey  InitialValue  Value  JourneyGroup  JGroup
0    12        1           3.0      4             1       1
1    12        1           4.0      5             1       1
2    12        0           NaN      7             1       1
3    12        0           NaN      2             1       1
4    12        1           5.0      8             2       2
5    12        0           NaN      9             2       2
6    13        1           3.0      4             3       3
7    13        1           4.0      5             3       3
8    13        0           NaN      7             3       3
9    13        0           NaN      6             3       3
10   13        1           1.0      2             3       3
11   13        0           NaN      9             0       0

Объяснение:

Групповой день и найти началопоездки и задайте все дни в этом дне, как в «Путешествии», так как мы не уверены, когда поездка останавливается:

df.groupby('Day')['Journey'].cummax()

Далее, используйте это в новой группе, чтобы найти первое значение в началеотключите и скопируйте его по длине групп, используя преобразование.

df.groupby(['Day',df.groupby('Day')['Journey'].cummax()])['Value'].transform('first')

Используйте, сдвиг, чтобы сравнить со следующей записью.Если сравнение меньше чем, возвращаемое True или изменение даты возвращают True, это указывает на конец старого путешествия и начало нового.Используйте cumsum для увеличения счетчика.

Затем, используя этот индекс количества, необходимо замаскировать запись, которая начинает новую группу с поездкой = 0.

m = t_num.diff().bfill().eq(1) & df.Journey.eq(0)
t_num = t_num.mask(m,0)

Это действительно простоНачните.Я не чувствую, что этот код достаточно надежен, чтобы передать другой набор данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...