Ситуация:
У меня есть фрейм данных python/pandas с одним столбцом и столбцом индекса. Столбец индекса является форматом даты и времени регистрируется каждую минуту, поэтому разница между двумя последовательными строками индекса всегда равна одной минуте, поскольку строки сортируются в порядке индекса. Другой столбец представляет идентификатор единицы.
"Unit_id" меняется время от времени почти случайным образом.
Эта проблема:
Я хотел бы добавить третий столбец с названием "Цикл", который подсчитывает прошедшие минуты как целые числа от начальной точки данного идентификатора устройства до конечной точки этого идентификатора устройства. Всякий раз, когда появляется новый идентификатор устройства, счетчик должен перезагружать и перезапускать с 1.
Поэтому в основном я хотел бы выглядеть следующим образом:
До сих пор я пытался создать формулу без индекса datetime (однако это было бы оптимальным решением), которое просто делает обычный счетчик и сбрасывается при каждом новом Unit_id. Вот мой код:
def ciklus_csinalo(str_Unit_id):
if 'old_Unit_id' in locals():
if str_Unit_id != old_Unit_id:
old_Unit_id = str_Unit_id
counter = 1
return counter
else:
counter += counter
return counter
else:
old_Unit_id = str_Unit_id
counter = 1
return counter
df["Cycle"] = df["Unit_id"].apply(ciklus_csinalo)
К сожалению, код не работает, так как я получаю значение 1 в каждой строке.
Вопросы:
Заранее спасибо за вашу помощь!
Вы можете сделать это так, пусть data
будут вашим DataFrame
:
data['cycle'] = data.groupby('unit_id')['datetime'].transform(pd.Series.diff)
data.fillna(60, inplace=True)
data['cycle'] = data.groupby('unit_id')['cycle'].transform(pd.Series.cumsum)
print(data)
Выход
datetime unit_id cycle
0 2016-10-05 08:25:00 102/16 00:01:00
1 2016-10-05 08:26:00 102/16 00:02:00
2 2016-10-05 08:27:00 102/16 00:03:00
3 2016-10-05 08:28:00 102/16 00:04:00
4 2016-10-05 08:29:00 102/16 00:05:00
5 2016-10-05 08:30:00 103/16 00:01:00
6 2016-10-05 08:31:00 103/16 00:02:00
7 2016-10-05 08:32:00 103/16 00:03:00
8 2016-10-05 08:33:00 103/16 00:04:00
9 2016-10-05 08:34:00 103/16 00:05:00
10 2016-10-05 08:35:00 104/16 00:01:00
11 2016-10-05 08:36:00 104/16 00:02:00
12 2016-10-05 08:37:00 105/16 00:01:00
13 2016-10-05 08:38:00 105/16 00:02:00
14 2016-10-05 08:39:00 105/16 00:03:00
Если вам нужен последний столбец целых чисел, вы можете сделать это следующим образом:
data['cycle'] = data.groupby('unit_id')['cycle'].transform(pd.Series.cumsum).transform(lambda e: (e.seconds//60) % 60)
IIUC, думаю, вы хотите, чтобы groupby
с помощью cumcount
:
df['cycle'] = df.groupby('Unit_ID').cumcount() + 1
Выход:
Datetime Unit_ID cycle
0 2016-10-05 08:25:00 102/16 1
1 2016-10-05 08:25:01 102/16 2
2 2016-10-05 08:25:02 102/16 3
3 2016-10-05 08:25:03 102/16 4
4 2016-10-05 08:25:04 102/16 5
5 2016-10-05 08:25:05 103/16 1
6 2016-10-05 08:25:06 103/16 2
7 2016-10-05 08:25:07 103/16 3
8 2016-10-05 08:25:08 103/16 4
9 2016-10-05 08:25:09 103/16 5
10 2016-10-05 08:25:10 104/16 1
11 2016-10-05 08:25:11 104/16 2
12 2016-10-05 08:25:12 105/16 1
13 2016-10-05 08:25:13 105/16 2
14 2016-10-05 08:25:14 105/16 3