大Pandas按时间和条件分组

2024-10-03 06:30:39 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个数据帧,我正试图创建基于两个条件的子事件标识-时间和标志。标志是当人员大于等于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     |

所以它需要某种分组方式来解释不同的事件id(这里是abc和xyz,但在我的真实数据集中有数百万个)。数据是按时间顺序排列的,行顺序在确定分组时很重要—两个标志之间的事件标识的行在一个子组中。每个子组都属于一个事件标识,子组的计数将重新开始,以获得一个新的事件标识

希望看到任何/所有的想法,我被难住了,但正在玩lambda函数。你知道吗


Tags: 数据eventid人员标志时间事件条件
2条回答
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

那你只需要重新分配。你知道吗

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

相关问题 更多 >