在解决"连续三天及以上人流量超过100的记录"问题时,MySQL方案作为力扣解决问题的方案通过窗口函数和分组技巧高效地识别连续记录。而Python与Pandas方案作为扩展则展示了在数据处理和分析方面的灵活性,通过行号变换和分组计数来筛选符合条件的数据行。
目录
题目描述
解题思路
完整代码
使用python- pandas扩展
题目描述
表:Stadium
+---------------+---------+ | Column Name | Type | +---------------+---------+ | id | int | | visit_date | date | | people | int | +---------------+---------+ visit_date 是该表中具有唯一值的列。 每日人流量信息被记录在这三列信息中:序号 (id)、日期 (visit_date)、 人流量 (people) 每天只有一行记录,日期随着 id 的增加而增加
编写解决方案找出每行的人数大于或等于 100
且 id
连续的三行或更多行记录。
返回按 visit_date
升序排列 的结果表。
查询结果格式如下所示。
示例 1:
输入:
Stadium
表:
+------+------------+-----------+
| id | visit_date | people |
+------+------------+-----------+
| 1 | 2017-01-01 | 10 |
| 2 | 2017-01-02 | 109 |
| 3 | 2017-01-03 | 150 |
| 4 | 2017-01-04 | 99 |
| 5 | 2017-01-05 | 145 |
| 6 | 2017-01-06 | 1455 |
| 7 | 2017-01-07 | 199 |
| 8 | 2017-01-09 | 188 |
+------+------------+-----------+
输出:
+------+------------+-----------+
| id | visit_date | people |
+------+------------+-----------+
| 5 | 2017-01-05 | 145 |
| 6 | 2017-01-06 | 1455 |
| 7 | 2017-01-07 | 199 |
| 8 | 2017-01-09 | 188 |
+------+------------+-----------+
解释:
id 为 5、6、7、8 的四行 id 连续,并且每行都有 >= 100 的人数记录。
请注意,即使第 7 行和第 8 行的 visit_date 不是连续的,输出也应当包含第 8 行,因为我们只需要考虑 id 连续的记录。
不输出 id 为 2 和 3 的行,因为至少需要三条 id 连续的记录。
解题思路
- 标记符合条件的行:首先,我们需要找出
people
大于等于100的行。 - 寻找连续的行:接着,我们需要找出这些行中
id
连续的部分。这一步稍微复杂,因为我们需要检查每行的id
是否与前一行的id
相差1。 - 统计连续行的数量:为了确保连续行至少有三行,我们可以使用窗口函数(如
ROW_NUMBER()
)来为这些连续行分组,并计算每组中的行数。 - 筛选结果:最后,我们只保留那些组内行数大于等于3的行。
完整代码
WITH RankedStadium AS (
SELECT
id,
visit_date,
people,
-- 为连续的行分配相同的组号
id - ROW_NUMBER() OVER (ORDER BY id) AS grp
FROM
Stadium
WHERE
people >= 100
),
GroupedStadium AS (
SELECT
id,
visit_date,
people,
grp,
-- 计算每个组内的行数
COUNT(*) OVER (PARTITION BY grp) AS cnt
FROM
RankedStadium
)
-- 选择那些组内行数大于等于3的记录
SELECT
id,
visit_date,
people
FROM
GroupedStadium
WHERE
cnt >= 3
ORDER BY
visit_date;
这段代码通过WITH
语句先创建了一个临时的RankedStadium视图来找出人数大于等于100的行,并为连续的行分配相同的组号。然后在GroupedStadium视图中,它计算每个组内的行数。最后,它选择那些组内行数大于等于3的记录,并按visit_date
排序。这样就能找到至少有三行连续id
且people
大于等于100的记录。
通过
使用python- pandas扩展
- 筛选符合条件的行:首先,我们需要筛选出
people
字段大于等于100的行。 - 寻找连续的行:然后,我们需要找到
id
连续的行。由于id
是连续增加的,我们可以通过检查当前行的id
是否比前一行的id
大1来判断是否连续。 - 标记连续的组:为了识别连续的行,我们可以用
id
减去行号来为每个连续的块创建一个唯一的标识符。 - 统计每组的行数:通过分组并统计每个组的行数,我们可以找出至少包含3行的组。
- 筛选结果:最后,我们筛选出那些组内行数大于等于3的行。
import pandas as pd
# 假设stadium_df是包含Stadium表数据的DataFrame
stadium_df = pd.DataFrame({
'id': [1, 2, 3, 4, 5, 6, 7, 8],
'visit_date': ['2017-01-01', '2017-01-02', '2017-01-03', '2017-01-04', '2017-01-05', '2017-01-06', '2017-01-07', '2017-01-09'],
'people': [10, 109, 150, 99, 145, 1455, 199, 188]
})
# 筛选people大于等于100的行
filtered_df = stadium_df[stadium_df['people'] >= 100]
# 通过id减去行号创建组标识符
filtered_df['group'] = filtered_df['id'] - filtered_df.reset_index().index
# 计算每组的行数
group_counts = filtered_df.groupby('group').size()
# 筛选出组内行数大于等于3的组
valid_groups = group_counts[group_counts >= 3].index
# 最终结果
result_df = filtered_df[filtered_df['group'].isin(valid_groups)].drop('group', axis=1)
print(result_df)