首页 > 解决方案 > 根据两个日期时间值对数据框进行分组

问题描述

我有一个数据集,它显示了一组进程的开始和结束时间戳。我想计算任何给定分钟内活动的进程数。pandas group/merge/join 操作似乎都不适合这里。这是一个测试数据集:

_range = pd.date_range(start='2020-03-01', end='2020-03-02', freq='1H')
start_ts = [random.choice(_range) for _ in range(48)]
end_ts = [r + datetime.timedelta(minutes=random.randint(1, 120)) for r in start_ts]

_processes = [random.choice(['Django', 'Flask', 'Pyramid', 'CherryPie']) for _ in start_ts]
df = pd.DataFrame({'start_time': start_ts, 'end_time': end_ts, 'process': _processes})
df.head()
           start_time            end_time    process
0 2020-03-01 00:00:00 2020-03-01 00:01:00     Django
1 2020-03-01 01:00:00 2020-03-01 01:04:00     Django
2 2020-03-01 02:00:00 2020-03-01 02:05:00      Flask
3 2020-03-01 03:00:00 2020-03-01 03:09:00      Flask
4 2020-03-01 04:00:00 2020-03-01 04:26:00  CherryPie

对于 2020/03/01 - 2020/03/02 之间的每 1 分钟间隔,我必须计算活动进程的数量。这是我能想到的一种解决方案:

这是一个示例解决方案:

df_stat = pd.DataFrame(index=pd.date_range(start='2020-03-01', end='2020-03-02', freq='1T'), columns=['count'])
for ts in df_stat.index:
    df_stat.loc[ts] = len(df[(df.start_time <= ts) & (df.end_time >= ts)])
df_stat.head()
                     count
2020-03-01 00:00:00      2
2020-03-01 00:01:00      2
2020-03-01 00:02:00      2
2020-03-01 00:03:00      2
2020-03-01 00:04:00      2

这看起来不是一个优雅的解决方案。当观察窗口很大时,迭代可能需要更长的时间。有没有我们可以在这里使用的原生 pandas 运算符?

标签: pythonpandas

解决方案


创建一分钟间隔的 DataFrame(或 Series)确实很合适。但是,根据输入,迭代原始 DataFrame 并相应地增加计数可能会更快(与您的解决方案相比):

df_stat = pd.DataFrame(index=pd.date_range(start='2020-03-01', end='2020-03-02', freq='1T'), 
                       columns=['count'])
df_stat.fillna(0, inplace=True)

for i in df.index:
    df_stat.loc[df.start_time.loc[i]:df.end_time.loc[i]] += 1

推荐阅读