python - Pandas 和 SQL 等效项(双重分组)
问题描述
我想计算当天持续时间总和超过 30 分钟(每个 ID)的天数
id date duration
111 2020-01-01 00:42:23
111 2020-01-01 00:23:23
111 2020-01-02 00:37:22
222 2020-01-02 00:13:08
222 2020-01-03 01:52:11
....
999 2020-01-31 00:15:21
999 2020-01-31 00:52:12
这是我用于计算的 SQL:
SELECT id, count(1)
FROM (
SELECT id
FROM statistic_prolonged
GROUP BY id, DAY(`date`)
HAVING SUM(TIMESTAMPDIFF(SECOND, date, date_end)) > 60 * 30
) as t
GROUP BY id
这相当于熊猫:
df['duration'] = (df['date_end'] - df['date']).dt.seconds
total_activity = (
df
.groupby(['id', pd.Grouper(key='date', freq='D')])
['duration'].sum() > dt.timedelta(minutes=30).seconds
.groupby('id')
.sum()
.astype(int)
)
print(len(total_activity))
但是我在相同的数据上得到了不同的结果。(Pandas 返回的行数比 SQL 多)
解决方案
首先要注意的是,我也受到了同样的“怪癖”的影响,那就是.dt.seconds
它并不总是能给你想要的答案。更好的选择是.dt.total_seconds()
接下来进行分组,
df.groupby([‘date’])[‘duration’].sum() > 30*60 # 30 Minutes
这将返回一个 True/False 数组,然后您可以简单地对这些值求和:
sum(df.groupby([‘date’])[‘duration’].sum() > 30*60)
推荐阅读
- json - Vue.js - 如何通过 axios 响应数据从对象中获取指定字段
- java - 初始化变量表示它未初始化
- asp.net - ASP.NET Core 身份注册 XSRF/CSRF 保护
- shell - Writing a cronjob using a script
- php - Do we upgrade PHP or Drupal / Joomla! Core first?
- git - How do I delete every change to my local git repository?
- ffmpeg - 在级联视频上添加徽标
- karate - 有人可以为我提供一个 pom.xml 文件来设置 UI 测试的空手道框架吗?
- swiftui - 如何在工作表视图上制作具有不透明度的背景颜色?
- ios - 在 iOS Swift 中实现方法时如何为闭包命名(语法问题)