熊猫集团 - 按时间和条件分开

时间:2017-11-09 23:50:20

标签: python pandas pandas-groupby

我有一个数据框,我试图根据两个条件创建子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功能。

2 个答案:

答案 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

然后你需要将其分配回来。