
本文介绍如何使用 pandas 快速计算每日在园人数及所有人累计停留天数,核心是通过 `entry - exit` 的差值累加得到每日在园人数,再对每日人数求和即得总人天数。
在人员进出管理、园区 occupancy 分析或资源调度场景中,常需统计“人×天”(person-days)这一关键指标——即所有人员在指定时段内停留的总天数。给定每日新增入场人数(entry_persons)与离场人数(exit_persons),我们需动态维护每日在园人数(即库存式累积),并最终求其时间序列之和。
关键逻辑在于:每日在园人数 = 前一日剩余人数 + 今日入场人数 − 今日离场人数。这本质上是一个带初始状态的累积差分过程,而 Pandas 的 cumsum() 正是为此类问题设计的高效工具。
假设原始数据如下:
import pandas as pd
df = pd.DataFrame({
'day': [1, 2, 3, 4, 5],
'entry_persons': [4, 2, 3, 5, 0],
'exit_persons': [0, 1, 4, 0, 1]
})只需一行代码即可计算每日在园人数:
df['total_on_campus'] = (df['entry_persons'] - df['exit_persons']).cumsum()
执行后得到:
| day | entry_persons | exit_persons | total_on_campus |
|---|---|---|---|
| 1 | 4 | 0 | 4 |
| 2 | 2 | 1 | 5 |
| 3 | 3 | 4 | 4 |
| 4 | 5 | 0 | 9 |
| 5 | 0 | 1 | 8 |
✅ 注意:cumsum() 默认从首行开始累加,天然契合“第1天无历史存量,直接为当日净流入”的业务前提(即初始园内人数为 0)。若实际存在期初存量(如第0天已有 N 人在园),可先在 DataFrame 首行插入一行 entry=N, exit=0,或直接将 cumsum() 结果加上初始值。
最终累计停留总天数(即所有人的停留天数之和)即为 total_on_campus 列的和:
total_person_days = df['total_on_campus'].sum() # 输出:30
也可一步到位(无需中间列):
total_person_days = (df['entry_persons'] - df['exit_persons']).cumsum().sum()
⚠️ 注意事项:
- 该方法隐含关键假设:所有离场者均来自此前在园人员(即不出现“负库存”)。若数据中存在某日 exit > 当前累计在园人数,cumsum 结果将为负,业务上不合理。建议增加校验:
net_flow = df['entry_persons'] - df['exit_persons'] if (net_flow.cumsum() < 0).any(): raise ValueError("Detected invalid exit: more people exited than were ever present.") - 若需支持多园区、多分组统计,可结合 groupby(...).apply(lambda g: (g['entry'] - g['exit']).cumsum().sum()) 扩展。
综上,利用 (entry - exit).cumsum() 计算滚动在园人数,再调用 .sum() 汇总,是解决此类“累计人天”问题最简洁、向量化、符合 Pandas 设计哲学的标准解法。










