作者:小小明来自一位群友的需求:
文章图片
求每个level列等于2之间的level等于1或3的dwell time的和。level列碰到2断开便断开,中间等于1或3的行,对dwell time列聚合求和。
要解决这个问题,只需要自定义分组规则即可。
首先,我们读取测试数据:
import pandas as pddf = 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 |
为了排除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 |
【数据处理|Pandas实例|自定义截断分组】开始计算分组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
结果:
文章图片
已经顺利计算出结果,但如果严格要求聚合结果只出现在每组最后一行,计算过程就稍微麻烦一点。
主要是需要在计算分组序号的同时,保存结果行的位置,完整代码如下:
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
文章图片
如果要求保留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
文章图片
推荐阅读
- py|【飞浆百度领航团零基础Python】学习笔记
- python自学——数据类型之列表
- 1001 A+B Format
- Python基础|六、Python基础(封装、继承、多态)
- Python|百度飞桨领航团零基础Python速成营课程总结
- paddle课程|【paddle领航团基础python课程】三岁水课—结营大作业
- python|python 计算器 casio_Python编程之计算器/字符及界面
- python学习|python应用学习系列笔记
- python学习|python应用学习(一)——python生成二维码