
本教程详细介绍了如何在pandas dataframe中高效统计多列日期数据落在指定时间范围内的行数。针对常见误区,文章提出了一种向量化的解决方案,通过日期类型转换、布尔逻辑筛选和列求和,精确计算每个阶段在不同时间窗口内的事件发生次数,为构建业务漏斗图提供数据支持,并展示了如何将其扩展应用于多个日期区间。
在数据分析中,我们经常需要处理包含时间戳的多阶段流程数据,例如用户在产品不同阶段的进入日期。为了分析流程效率或构建漏斗图,一个常见的需求是统计在特定日期范围内,每个阶段有多少条记录。本教程将深入探讨如何使用Pandas高效准确地完成这项任务。
假设我们有一个DataFrame,其中每行代表一个记录,每列代表一个流程阶段,单元格中存储的是该记录进入对应阶段的日期。我们的目标是针对一系列预设的日期区间,计算每个阶段(列)有多少记录的日期落在这个区间内。
输入数据示例:
| stage 1 | stage 2 | stage 3 | |
|---|---|---|---|
| row 1 | 1/3/2023 | 4/3/2023 | 5/7/2023 |
| row 2 | 2/5/2023 | 2/6/2023 | 3/4/2023 |
| row 3 | 1/15/2023 | 6/3/2023 | 7/8/2023 |
一个常见的误区是尝试先使用 any() 聚合布尔条件,这会导致不准确的计数。例如,如果 row 3 的 stage 1 日期在范围内,而 stage 2 和 stage 3 不在,但错误的逻辑可能导致 row 3 在所有阶段都被计数。正确的做法是,对每个阶段(列)独立地进行日期范围检查和计数。
首先,我们需要创建一个示例DataFrame,并确保日期列被正确地转换为Pandas的datetime对象。这是进行日期比较的基础。
import pandas as pd
# 创建示例DataFrame
data = {
'stage 1': ['1/3/2023', '2/5/2023', '1/15/2023'],
'stage 2': ['4/3/2023', '2/6/2023', '6/3/2023'],
'stage 3': ['5/7/2023', '3/4/2023', '7/8/2023']
}
df = pd.DataFrame(data, index=['row 1', 'row 2', 'row 3'])
# 将所有日期列转换为datetime类型
# 使用errors='coerce'可以处理无法转换的值,将其设为NaT(Not a Time)
df_dates = df.apply(pd.to_datetime, errors='coerce')
print("原始DataFrame (日期已转换为datetime):")
print(df_dates)输出示例:
原始DataFrame (日期已转换为datetime):
stage 1 stage 2 stage 3
row 1 2023-01-03 00:00:00 2023-04-03 00:00:00 2023-05-07 00:00:00
row 2 2023-02-05 00:00:00 2023-02-06 00:00:00 2023-03-04 00:00:00
row 3 2023-01-15 00:00:00 2023-06-03 00:00:00 2023-07-08 00:00:00为了准确统计每个阶段在给定日期区间内的行数,我们需要执行以下步骤:
# 定义日期区间
start_date = pd.to_datetime('2023-1-1')
end_date = pd.to_datetime('2023-3-30')
# 步骤1: 检查日期是否大于等于起始日期
mask_ge_start = df_dates.ge(start_date)
print("\n日期 >= start_date 的布尔DataFrame:")
print(mask_ge_start)
# 步骤2: 检查日期是否小于等于结束日期
mask_le_end = df_dates.le(end_date)
print("\n日期 <= end_date 的布尔DataFrame:")
print(mask_le_end)
# 步骤3: 结合两个布尔条件
# 只有当日期同时满足 >= start_date 和 <= end_date 时才为True
final_mask = mask_ge_start & mask_le_end
print("\n最终布尔DataFrame (日期在区间内):")
print(final_mask)
# 步骤4: 按列求和,得到每个阶段的计数
counts_single_range = final_mask.sum()
print("\n单日期区间内各阶段的计数:")
print(counts_single_range)输出示例:
日期 >= start_date 的布尔DataFrame:
stage 1 stage 2 stage 3
row 1 True True True
row 2 True True True
row 3 True True True
日期 <= end_date 的布oolDataFrame:
stage 1 stage 2 stage 3
row 1 True False False
row 2 True True True
row 3 True False False
最终布尔DataFrame (日期在区间内):
stage 1 stage 2 stage 3
row 1 True False False
row 2 True True True
row 3 True False False
单日期区间内各阶段的计数:
stage 1 2
stage 2 1
stage 3 1
dtype: int64这种方法利用了Pandas的向量化操作,避免了显式循环,效率更高,并且逻辑清晰。
为了实现漏斗分析中不同时间区间的对比,我们可以将上述单日期区间的统计方法封装成一个函数,并遍历一个日期区间列表。
def count_stages_by_date_ranges(df_dates: pd.DataFrame, date_ranges: list):
"""
统计DataFrame中各阶段在多个日期区间内的记录数。
参数:
df_dates (pd.DataFrame): 包含datetime类型日期数据的DataFrame。
date_ranges (list): 包含元组的列表,每个元组代表一个日期区间 (start_date, end_date)。
返回:
pd.DataFrame: 索引为日期区间字符串,列为阶段名称,值为对应计数。
"""
results = {}
for i, (start, end) in enumerate(date_ranges):
start_dt = pd.to_datetime(start)
end_dt = pd.to_datetime(end)
# 进行向量化比较和求和
mask = (df_dates.ge(start_dt)) & (df_dates.le(end_dt))
counts = mask.sum()
# 将结果存储到字典中,键为日期区间字符串
range_label = f"{start_dt.strftime('%m/%d/%Y')} - {end_dt.strftime('%m/%d/%Y')}"
results[range_label] = counts.tolist() # 转换为列表以便创建DataFrame
# 将结果字典转换为DataFrame
# 确保列名与原始df_dates的列名一致
stage_cols = df_dates.columns.tolist()
output_df = pd.DataFrame.from_dict(results, orient='index', columns=stage_cols)
return output_df
# 定义多个日期区间
date_intervals = [
('2023-1-1', '2023-4-1'),
('2023-4-1', '2023-7-1'),
('2023-7-1', '2023-10-1')
]
# 调用函数进行统计
funnel_counts_df = count_stages_by_date_ranges(df_dates, date_intervals)
print("\n多日期区间内各阶段的计数 (漏斗分析数据):")
print(funnel_counts_df)输出示例:
多日期区间内各阶段的计数 (漏斗分析数据):
stage 1 stage 2 stage 3
01/01/2023 - 04/01/2023 2 1 1
04/01/2023 - 07/01/2023 0 2 1
07/01/2023 - 10/01/2023 0 1 1这个输出与我们期望的漏斗分析数据表完全一致。通过这种方式,我们获得了在不同时间窗口内,每个阶段的事件发生次数,这些数据可以直接用于绘制漏斗图,分析流程的转化和流失情况。
本教程提供了一种在Pandas DataFrame中高效、准确地统计多列日期数据落在指定时间区间内行数的解决方案。通过利用Pandas的向量化操作进行元素级别的日期比较和布尔掩码求和,我们避免了传统循环或不当聚合可能导致的错误和低效。这种方法不仅适用于单日期区间统计,也能灵活扩展到多个日期区间,为漏斗分析等业务场景提供了强大的数据处理能力。掌握这一技巧,将显著提升您在处理时间序列和多阶段流程数据时的效率和准确性。
以上就是Pandas中多列日期区间行数统计与漏斗分析的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号