我有一个数据框,我试图根据两个条件创建子event_ids - 时间和标志。该标志是当人> gt = = 600时,创建一个新的子组。
数据看起来像这样:
| event_id | timestamp | people |
| abc | 12:00 | 1 |
| abc | 12:01 | 3 |
| abc | 12:02 | 5 |
| abc | 12:04 | 600 |
| abc | 12:10 | 4 |
| abc | 12:15 | 7 |
| abc | 12:20 | 1700 |
| abc | 12:30 | 1 |
| abc | 12:31 | 1 |
| xyz | 12:32 | 1 |
| xyz | 12:40 | 750 |
| xyz | 12:50 | 1 |
我想要的结果如下:
| event_id | timestamp | people | subgroup |
| abc | 12:00 | 1 | A |
| abc | 12:01 | 3 | A |
| abc | 12:02 | 5 | A |
| abc | 12:04 | 600 | A |
| abc | 12:10 | 4 | B |
| abc | 12:15 | 7 | B |
| abc | 12:20 | 1700 | B |
| abc | 12:30 | 1 | C |
| abc | 12:31 | 1 | C |
| xyz | 12:32 | 1 | A |
| xyz | 12:40 | 750 | A |
| xyz | 12:50 | 1 | B |
所以它需要某种分组来考虑不同的event_ids(这里是abc和xyz,但我的真实数据集中有数百万)。数据是按时间排序的,并且在确定分组时行顺序很重要 - 两个标志之间的event_id的行在一个子组中。每个子组属于event_id,并且计数子组重新启动新的event_id。
很想看到任何/所有的想法,我很难过,但现在玩lambda功能。
答案 0 :(得分:3)
from string import ascii_uppercase
m = dict(enumerate(ascii_uppercase))
def trickery(x):
c = (x.values >= 600)[::-1].cumsum()[::-1]
return c.max() - c
df.assign(subgroup=df.groupby('event_id').people.transform(trickery).map(m))
event_id timestamp people subgroup
0 abc 12:00 1 A
1 abc 12:01 3 A
2 abc 12:02 5 A
3 abc 12:04 600 A
4 abc 12:10 4 B
5 abc 12:15 7 B
6 abc 12:20 1700 B
7 abc 12:30 1 C
8 abc 12:31 1 C
9 xyz 12:32 1 A
10 xyz 12:40 750 A
11 xyz 12:50 1 B
答案 1 :(得分:3)
df.groupby('event_id').people.apply(lambda x :(x>=600).shift().fillna(0).cumsum()).\
map({0:'A',1:'B',2:'C'})
Out[207]:
0 A
1 A
2 A
3 A
4 B
5 B
6 B
7 C
8 C
9 A
10 A
11 B
Name: people, dtype: object
然后你需要将其分配回来。