Pandas实例|自定义截断分组

举报
小小明-代码实体 发表于 2021/10/11 22:48:29 2021/10/11
【摘要】 作者:小小明 来自一位群友的需求: 求每个level列等于2之间的level等于1或3的dwell time的和。level列碰到2断开便断开,中间等于1或3的行,对dwell time...

作者:小小明

来自一位群友的需求:

image-20210209152208193

求每个level列等于2之间的level等于1或3的dwell time的和。level列碰到2断开便断开,中间等于1或3的行,对dwell time列聚合求和。

要解决这个问题,只需要自定义分组规则即可。

首先,我们读取测试数据:

import pandas as pd

df = pd.read_csv("20200922-02.csv")
df

  
 
level dwell time dwell time of level 1+3
0 2 7.8750 NaN
1 3 0.9065 NaN
2 2 4.0000 NaN
3 1 0.5310 NaN
4 3 1.0625 NaN
13093 2 3.7500 NaN
13094 1 0.8750 NaN
13095 3 2.6250 NaN
13096 1 3.2500 NaN
13097 3 2.2500 NaN

13098 rows × 3 columns

为了排除level等于其他数值的数据的干扰,我们取出只需要处理的数据:

df.query('level in (1,2,3)', inplace=True)

  
 
level dwell time dwell time of level 1+3
0 2 7.8750 NaN
1 3 0.9065 NaN
2 2 4.0000 NaN
3 1 0.5310 NaN
4 3 1.0625 NaN
13093 2 3.7500 NaN
13094 1 0.8750 NaN
13095 3 2.6250 NaN
13096 1 3.2500 NaN
13097 3 2.2500 NaN

13030 rows × 3 columns

开始计算分组id:

group_ids = []
num = 0
for i, level in df.level.iteritems():
    if level == 2:
        num += 1
        group_ids.append(None)
    else:
        group_ids.append(num)
group_ids[:20]

  
 

结果:

[None, 1, None, 2, 2, None, 3, 3, 3, 3, 3, 3, None, 4, 4, None, 5, 5, None, 6]

  
 

只需要将不参与分组的对应行置为None即可,最终聚合结果将为空值。

计算结果:

df['dwell time of level 1+3'] = df.groupby(group_ids)['dwell time'].transform('sum')
df

  
 

结果:

image-20210209154632907

已经顺利计算出结果,但如果严格要求聚合结果只出现在每组最后一行,计算过程就稍微麻烦一点。

主要是需要在计算分组序号的同时,保存结果行的位置,完整代码如下:

df = pd.read_csv("20200922-02.csv")
df.query('level in (1,2,3)', inplace=True)
group_ids = []
mask = []
num = 0
last_i, last_level = -1, 2
for i, level in df.level.iteritems():
    if level == 2:
        num += 1
        group_ids.append(None)
        if last_level != 2:
            mask.append(last_i)
    else:
        group_ids.append(num)
    last_i, last_level = i, level
if last_level != 2:
    mask.append(last_i)
df.loc[mask,'dwell time of level 1+3'] = df.groupby(group_ids)['dwell time'].sum().values
df

  
 

image-20210209161855059

如果要求保留level不在[1,2,3]范围的行,可以先只对在[1,2,3]范围行进行计算,最终对原始数据进行赋值。

完整代码如下:

df = pd.read_csv("20200922-02.csv")
tmp = df.query('level in (1,2,3)')
group_ids = []
mask = []
num = 0
last_i, last_level = -1, 2
for i, level in tmp.level.iteritems():
    if level == 2:
        num += 1
        group_ids.append(None)
        if last_level != 2:
            mask.append(last_i)
    else:
        group_ids.append(num)
    last_i, last_level = i, level
if last_level != 2:
    mask.append(last_i)
df.loc[mask, 'dwell time of level 1+3'] = tmp.groupby(group_ids)['dwell time'].sum().values
df

  
 

image-20210209163030561

文章来源: xxmdmst.blog.csdn.net,作者:小小明-代码实体,版权归原作者所有,如需转载,请联系作者。

原文链接:xxmdmst.blog.csdn.net/article/details/113772450

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。