Python 在差异条件下在数据帧中写入值(日期时间)
我想在“开始时间”列中写入分组时间测量第一次非零出现的日期时间值,并将分组时间测量最后一次出现的时间写入“结束时间”列。如果分组测量值为0,“开始时间”和“结束时间”应等于0 我用diffna()选项尝试了各种diff(),但没有成功。这是我的密码:Python 在差异条件下在数据帧中写入值(日期时间),python,pandas,datetime,Python,Pandas,Datetime,我想在“开始时间”列中写入分组时间测量第一次非零出现的日期时间值,并将分组时间测量最后一次出现的时间写入“结束时间”列。如果分组测量值为0,“开始时间”和“结束时间”应等于0 我用diffna()选项尝试了各种diff(),但没有成功。这是我的密码: import pandas as pd import numpy as np import datetime current_time=datetime.datetime.now() L=[] for i in range(22): L
import pandas as pd
import numpy as np
import datetime
current_time=datetime.datetime.now()
L=[]
for i in range(22):
L.append(current_time+datetime.timedelta(milliseconds=(i*500)))
# Define input dataframe
df = {'value': [1,1,1,0,0,0,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,0],
'time': L}
df = pd.DataFrame(df,columns= ['value','time'])
# print("Dataframe is:\n",df)
print("Grouping data according to servo positions, please wait...")
df['grouped_measurement'] = df['value'].diff().fillna(df['value']).eq(1).cumsum().mask(df['value'] == 0, 0)
df['Start_time'] = df['grouped_measurement'].diff().fillna(df['time'])
df['End_time'] = df['grouped_measurement'].diff().fillna(df['time'])
print("Dataframe is:\n",df)
我的实际结果是:
value time grouped_measurement Start_time End_time
0 1 2019-08-31 19:14:42.259304 1 1.567279e+18 1.567279e+18
1 1 2019-08-31 19:14:42.759304 1 0.000000e+00 0.000000e+00
2 1 2019-08-31 19:14:43.259304 1 0.000000e+00 0.000000e+00
3 0 2019-08-31 19:14:43.759304 0 -1.000000e+00 -1.000000e+00
4 0 2019-08-31 19:14:44.259304 0 0.000000e+00 0.000000e+00
5 0 2019-08-31 19:14:44.759304 0 0.000000e+00 0.000000e+00
6 1 2019-08-31 19:14:45.259304 2 2.000000e+00 2.000000e+00
7 1 2019-08-31 19:14:45.759304 2 0.000000e+00 0.000000e+00
8 1 2019-08-31 19:14:46.259304 2 0.000000e+00 0.000000e+00
9 1 2019-08-31 19:14:46.759304 2 0.000000e+00 0.000000e+00
10 1 2019-08-31 19:14:47.259304 2 0.000000e+00 0.000000e+00
11 0 2019-08-31 19:14:47.759304 0 -2.000000e+00 -2.000000e+00
12 0 2019-08-31 19:14:48.259304 0 0.000000e+00 0.000000e+00
13 0 2019-08-31 19:14:48.759304 0 0.000000e+00 0.000000e+00
14 0 2019-08-31 19:14:49.259304 0 0.000000e+00 0.000000e+00
15 1 2019-08-31 19:14:49.759304 3 3.000000e+00 3.000000e+00
16 1 2019-08-31 19:14:50.259304 3 0.000000e+00 0.000000e+00
17 1 2019-08-31 19:14:50.759304 3 0.000000e+00 0.000000e+00
18 1 2019-08-31 19:14:51.259304 3 0.000000e+00 0.000000e+00
19 1 2019-08-31 19:14:51.759304 3 0.000000e+00 0.000000e+00
20 1 2019-08-31 19:14:52.259304 3 0.000000e+00 0.000000e+00
21 0 2019-08-31 19:14:52.759304 0 -3.000000e+00 -3.000000e+00
而预期产出如下:
value time grouped_measurement Start_time End_time
0 1 2019-08-31 19:14:42.259304 1 2019-08-31 19:14:42.259304 2019-08-31 19:14:43.259304
1 1 2019-08-31 19:14:42.759304 1 2019-08-31 19:14:42.259304 2019-08-31 19:14:43.259304
2 1 2019-08-31 19:14:43.259304 1 2019-08-31 19:14:42.259304 2019-08-31 19:14:43.259304
3 0 2019-08-31 19:14:43.759304 0 0 0
4 0 2019-08-31 19:14:44.259304 0 0 0
5 0 2019-08-31 19:14:44.759304 0 0 0
6 1 2019-08-31 19:14:45.259304 2 2019-08-31 19:14:45.259304 2019-08-31 19:14:47.259304
7 1 2019-08-31 19:14:45.759304 2 2019-08-31 19:14:45.259304 2019-08-31 19:14:47.259304
8 1 2019-08-31 19:14:46.259304 2 2019-08-31 19:14:45.259304 2019-08-31 19:14:47.259304
9 1 2019-08-31 19:14:46.759304 2 2019-08-31 19:14:45.259304 2019-08-31 19:14:47.259304
10 1 2019-08-31 19:14:47.259304 2 2019-08-31 19:14:45.259304 2019-08-31 19:14:47.259304
11 0 2019-08-31 19:14:47.759304 0 0 0
12 0 2019-08-31 19:14:48.259304 0 0 0
13 0 2019-08-31 19:14:48.759304 0 0 0
14 0 2019-08-31 19:14:49.259304 0 0 0
15 1 2019-08-31 19:14:49.759304 3 2019-08-31 19:14:49.759304 2019-08-31 19:14:52.259304
16 1 2019-08-31 19:14:50.259304 3 2019-08-31 19:14:49.759304 2019-08-31 19:14:52.259304
17 1 2019-08-31 19:14:50.759304 3 2019-08-31 19:14:49.759304 2019-08-31 19:14:52.259304
18 1 2019-08-31 19:14:51.259304 3 2019-08-31 19:14:49.759304 2019-08-31 19:14:52.259304
19 1 2019-08-31 19:14:51.759304 3 2019-08-31 19:14:49.759304 2019-08-31 19:14:52.259304
20 1 2019-08-31 19:14:52.259304 3 2019-08-31 19:14:49.759304 2019-08-31 19:14:52.259304
21 0 2019-08-31 19:14:52.759304 0 0 0
你很接近!在您创建的“分组测量”列上使用groupby
df['grouped_measurement'] = df['value'].diff().fillna(1).eq(1).cumsum().where(df['value'].ne(0))
result = (df.join(df.groupby('grouped_measurement')['time']
.agg([('Start_time','min'),('End_time','max')])
, on='grouped_measurement')
.fillna(0,downcast='infer'))
您可能需要pandas 0.25
才能使用.agg([('Start\u time','min'),('End\u time','max')]
编辑
假设时间列已排序,则以下方法将不依赖于groupby
label_start_end = df['value'].diff().fillna(1, downcast='infer')
df['Start_time'] = df['time'].where(label_start_end.eq(1)).ffill().where(df['value'].eq(1),0)
df['End_time'] = df['time'].where(label_start_end.eq(-1)).bfill().where(df['value'].eq(1),0)
编辑2(datetime列无0)
非常接近!请在您创建的“分组测量”列中使用groupby
df['grouped_measurement'] = df['value'].diff().fillna(1).eq(1).cumsum().where(df['value'].ne(0))
result = (df.join(df.groupby('grouped_measurement')['time']
.agg([('Start_time','min'),('End_time','max')])
, on='grouped_measurement')
.fillna(0,downcast='infer'))
您可能需要pandas 0.25
才能使用.agg([('Start\u time','min'),('End\u time','max')]
编辑
假设时间列已排序,则以下方法将不依赖于groupby
label_start_end = df['value'].diff().fillna(1, downcast='infer')
df['Start_time'] = df['time'].where(label_start_end.eq(1)).ffill().where(df['value'].eq(1),0)
df['End_time'] = df['time'].where(label_start_end.eq(-1)).bfill().where(df['value'].eq(1),0)
编辑2(datetime列无0)
你知道如何提高效率吗?我的熊猫数据帧非常大,包含2-5000万行。执行
df['groupped_measurement']=df['value'].diff().fillna(1.eq(1.cumsum().where(df['value'].ne(0))
持续时间不到1秒。当我执行结果=
行时,它持续时间超过30秒,这很长…@Tomasz,它已经过优化。如果使用groupby转换或应用,它将需要更长的时间。我想你有很多组?试着运行df.groupby('groupped_measurement')['time'].agg([(‘开始时间’、‘最小’、‘结束时间’、‘最大’))
在我的例子中,要查看需要多长时间,在执行任何操作之前,“时间”列显然是经过排序的。使用不依赖groupby的方法,操作时间从30秒减少到了7秒,这很好,但“开始时间”和“结束时间”始终为0。另一方面df.groupby(“groupped\u测量”)[“时间”].agg([('Start_time','min'),('End_time','max'))
没有做我想做的事情,因为它会分组。@你确定吗?我可以复制结果(使用非0的Start_time和End_time)你知道如何提高效率吗?我的pandas数据框非常大,包含2-50百万行。df['groupped_measurement'的执行]=df['value'].diff().fillna(1).eq(1).cumsum().where(df['value'].ne(0))
持续时间不到1秒。当我执行结果=
行时,它持续时间超过30秒,这很长…@Tomasz,它已经过优化。如果使用groupby转换或应用,它将需要更长的时间。我想你有很多组?试着运行df.groupby('groupped_measurement')['time'].agg([(‘开始时间’、‘最小’、‘结束时间’、‘最大’))
在我的例子中,要查看需要多长时间,在执行任何操作之前,“时间”列显然是经过排序的。使用不依赖groupby的方法,操作时间从30秒减少到了7秒,这很好,但“开始时间”和“结束时间”始终为0。另一方面df.groupby(“groupped\u测量”)[“时间”].agg([('Start\u time','min'),('End\u time','max'))
不执行我想要的操作,因为它会分组。@您确定吗?我可以复制结果(使用非0的Start\u time和End\u time)