情况:
我有一个带有一列和索引列的python / pandas数据框。索引列是一种日期时间格式,并且每分钟都会记录一次,因此,两个连续的索引行之间的差异始终为一分钟,因为这些行按索引顺序进行了排序。另一列代表一个单位ID。
“ Unit_id”几乎随时随地变化。
问题:
我想添加第三列“ Cycle”,它将从给定单位ID的起点到该单位ID的终点将经过的分钟数作为整数进行计数。每当有新的设备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的值。
问题:
提前感谢您的帮助!
答案 0 :(得分:2)
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
答案 1 :(得分: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)