2017-08-09 109 views
1

我在python一个数据帧。数据帧的列是Id,loc_time,loc_number, status组多个记录作为一个记录和分配值在python数据帧

数据低于:

Id loc_time loc_number status 
1 01:25.5  1105  testing on 
2 02:25.9  1105  testing off 
3 03:28.5  1105  testing off 
4 04:25.5  1105  testing off 
5 05:25.9  1105  testing on 
6 06:25.5  1105  testing on 
7 07:25.9  1105  testing off 
8 08:25.6  1105  testing off 
9 09:25.9  1106  testing on 
10 10:25.6  1105  testing on 
11 11:26.0  1105  testing off 
12 12:25.6  1105  testing off 
13 13:26.0  1105  testing on 
14 14:25.6  1106  testing on 
15 15:26.0  1105  testing off 
16 16:25.6  1105  testing off 
17 17:26.0  1105  testing on 
18 18:25.7  1105  testing on 
19 19:26.0  1105  testing off 
20 20:25.7  1105  testing off 
21 21:26.1  1105  testing on 
22 22:25.7  1106  testing on 
23 22:33.7  1107  testing on 
24 23:26.1  1105  testing off 
25 24:25.7  1105  testing off 
26 25:26.1  1105  testing on 
27 27:25.7  1105  testing on 
28 22:35.7  1106  testing off  

现在我想创建一个列Idloc_timeloc_numberstatuscount新的数据帧。

Id loc_time loc_number status   count 
1 03:28.5  1105  testing on  03 
2 06:25.5  1105  testing   03 
3 10:25.6  1105  testing   03 
4 13:26.0  1105  testing   03 
5 17:26.0  1105  testing   03 
6 20:25.7  1105  testing   03 
7 24:25.7  1105  testing   03 
8 27:25.7  1105  testing off  02 
9 22:25.7  1106  testing on  03 
10 22:35.7  1106  testing off  01 
11 22:33.7  1107  testing on  01 

我想组的前十个时间戳记录作为一个记录,并指定测试的地位上也算没有记录。

我想要做同样为未来十年的记录,并指定为测试状态。

对于数据的最后一组我要的地位测试过

我该怎么办呢?

当1 - 10个时间戳组合在一起为相同的loc_number然后状态测试。

如果有1- 10时间戳相同loc_number后超过10个时间戳则状态是测试 等

如果有前一组的10个时间戳的后小于10个时间戳同样loc_number则状态是测试停止

组合在一起,应该测试了最后的时间戳。

+0

只要环旧DF与步长10,并在新添加的步骤之间的值DF等'对于i在范围(0,LEN(DF),10):DF2 = pd.DataFrame({ “loc_time”:NP。sum(df [“loc_time] [i:i + 10])})' – 2Obe

+0

不应该为您的预期结果的最后一行测试关闭吗? – Alexander

+0

@Alexander否,因为它是一个新的'loc_number',数字,那么它应该''测试' –

回答

1

现在应该工作。如果您不想索引该列上的数据帧,则始终可以删除df2 = df2.set_index('ID')(最后一行)。

首先,我需要通过loc_numberloc_time,以便数据帧进行排序。

接下来,我需要为这些不同大小的组创建连续的数字块(例如1,1,1,2,2,1,1,1,2,2,2,3,3,假设两个loc_numbers) 。为此,我对loc_number进行了分组,并使用列表理解来将每个项目的索引除以分组大小(例如3),从而执行使用分区划分的变换。

transform(lambda group: [i // group_size for i in range(len(group))]))

接下来,我集中在那loc_number而且这个新loc_counter做聚合的其余部分。

我用一个列表理解来获得各组的第一个和最后一个项目。然后,我根据情况使用.loc将状态设置为testing_offtesting_on

group_size = 3 
df.sort_values(['loc_number', 'loc_time'], inplace=True) 
df2 = (
    df 
    .assign(
     status='testing', 
     loc_counter=df.groupby('loc_number')['loc_number'] 
         .transform(lambda group: [i // group_size for i in range(len(group))])) 
    .groupby(['loc_number', 'loc_counter']) 
    .agg({'loc_time': 'last', 'loc_number': 'last', 'loc_counter': 'count', 'status': 'last'}) 
    .rename(columns={'loc_counter': 'count'}) 
    .reset_index(drop=True) 
) 

df2['ID'] = range(1, len(df2) + 1) 
df2 = df2[['ID', 'loc_time', 'loc_number', 'status', 'count']] 

first_group_items = [group[0] for group in df2.groupby('loc_number').groups.itervalues()] 
last_group_items = [group[-1] for group in df2.groupby('loc_number').groups.itervalues()] 

df2.loc[last_group_items, 'status'] = 'testing_off' 
df2.loc[first_group_items, 'status'] = 'testing_on' 

df2 = df2.set_index('ID') 

>>> df2 
    loc_time loc_number  status count 
ID           
1 03:28.5  1105 testing_on  3 
2 06:25.5  1105  testing  3 
3 10:25.6  1105  testing  3 
4 13:26.0  1105  testing  3 
5 17:26.0  1105  testing  3 
6 20:25.7  1105  testing  3 
7 24:25.7  1105  testing  3 
8 27:25.7  1105 testing_off  2 
9 22:25.7  1106 testing_on  3 
10 22:35.7  1106 testing_off  1 
11 22:33.7  1107 testing_on  1