如何使用Pandas按分组汇总同时间戳下多移动方式的流量并仅在指定行显示总和?
问题:分组计算交通流量总和并仅在指定Movement行显示结果
我有如下格式的交通流量数据:
intersection_id start_time approach movement volume 799028 12:00:00 AM Southbound Right 2 799028 12:15:00 AM Southbound Right 4 799028 12:30:00 AM Southbound Right 6 799028 12:00:00 AM Southbound Thru 4 799028 12:15:00 AM Southbound Thru 6 799028 12:30:00 AM Southbound Thru 8 799028 12:00:00 AM Southbound Left 6 799028 12:15:00 AM Southbound Left 8 799028 12:30:00 AM Southbound Left 10 799028 12:00:00 AM Southbound U-turn 10 799028 12:15:00 AM Southbound U-turn 12 799028 12:30:00 AM Southbound U-turn 14
我的需求是:
- 按
intersection_id、start_time、approach进行分组 - 对同一分组下
Right、Thru、Left、U-turn的volume值求和 - 仅将求和结果显示在对应分组的
Right行中,其他movement(Thru、Left、U-turn)的行显示为nan
期望的输出结果如下:
intersection_id start_time approach movement volume 799028 12:00:00 AM Southbound Right 24 799028 12:15:00 AM Southbound Right 30 799028 12:30:00 AM Southbound Right 38 799028 12:00:00 AM Southbound Thru nan 799028 12:15:00 AM Southbound Thru nan 799028 12:30:00 AM Southbound Thru nan 799028 12:00:00 AM Southbound Left nan 799028 12:15:00 AM Southbound Left nan 799028 12:30:00 AM Southbound Left nan 799028 12:00:00 AM Southbound U-turn nan 799028 12:15:00 AM Southbound U-turn nan 799028 12:30:00 AM Southbound U-turn nan
我尝试了两种方法都没成功:
- 方法一:用
transform计算分组总和,但无法生成nan,所有行都会显示总和:
df['app_sum'] = df.groupby(['intersection_id','start_time','approach'], as_index=False)['volume'].transform('sum')
- 方法二:尝试用滚动窗口,但逻辑错误,因为不存在对应的窗口:
indexer = pd.api.indexers.FixedForwardWindowIndexer(window_size=4, offset=-3) df['app_sum'] = ( df.groupby(['intersection_id','start_time','approach'])['volume'].rolling(window=indexer).sum().droplevel(0) )
请问有什么可行的解决方案?
解决方案
我来给你提供一个简单直接的可行方案,核心思路是先算出每个分组的总流量,再通过条件判断只在Right行保留总和,其他行替换成nan。具体代码和逻辑如下:
代码实现
import pandas as pd import numpy as np # 假设你的数据已经加载为DataFrame df df['volume'] = np.where( df['movement'] == 'Right', # 判断当前行是不是Right类型 # 计算对应分组的总流量 df.groupby(['intersection_id', 'start_time', 'approach'])['volume'].transform('sum'), np.nan # 非Right行赋值为nan )
逻辑拆解
- 分组计算总和:
groupby(['intersection_id', 'start_time', 'approach'])['volume'].transform('sum')会给每一行都添加上它所在分组的总流量,这一步能正确获取每个时间点、每个路口、每个方向的总流量; - 条件赋值:用
np.where做判断——只有当movement是Right的时候,才保留刚才算出的分组总和,其他所有类型的行(Thru、Left、U-turn)都替换成nan; - 自动适配所有分组:这个逻辑会自动遍历所有的
intersection_id和approach,不需要额外写循环或者复杂的窗口逻辑。
运行这段代码后,你的DataFrame就会完全符合你想要的输出格式啦~
内容的提问来源于stack exchange,提问作者joshuah9
相关产品推荐
相关产品推荐

