You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何更优雅地在Pandas DataFrame中分类并比较日期时间列?

寻找更Pythonic的方式统计两个时间段的独立访问次数

我有一个包含VisitDate(日期时间列)和VisitID(访问ID列)的DataFrame,需要对比两个时间段内的独立访问次数。目前的实现代码能得到正确结果,但写法不够Pythonic,想了解更优的实现方式。

输入数据

VisitID访问日期
11/1/2023
22/1/2023
43/1/2023
54/1/2023
65/1/2023

现有实现代码

import pandas as pd

df = pd.DataFrame({"VisitID":['1', '2', '4', '5', '6'],
"VisitDate": ['1/1/2023', '2/1/2023', '3/1/2023', '4/1/2023', '5/1/2023']})

df['VisitDate'] = pd.to_datetime(df['VisitDate'])
# 划分3个日期分类
df["Categorize Date Range"] = pd.cut(df['VisitDate'], 
       bins=[pd.Timestamp("1/1/2023"), pd.Timestamp("2/2/2023"), pd.Timestamp("3/31/2023"), pd.Timestamp("5/1/2023")], 
       labels=['Dates: 1/1/2023 - 2/1/2023', 0, "Dates: 4/1/2023 - 5/1/2023"],
        include_lowest=True,
       right=True)
# 过滤掉无关的日期分类
df = df[(df['Categorize Date Range'] != 0) & (df['Categorize Date Range'].notnull())].copy()
# 统计每个分类的独立访问次数
df.groupby(['Categorize Date Range'])['VisitID'].nunique()

现有代码输出

indexVisitID
Dates: 1/1/2023 - 2/1/20232
Dates: 4/1/2023 - 5/1/20232

优化实现方式

方式一:用np.select生成分组标签并过滤

直接定义目标时间段的条件和对应标签,避免冗余的中间分类(比如原代码中的0标签),逻辑更清晰:

import pandas as pd
import numpy as np

df = pd.DataFrame({"VisitID":['1', '2', '4', '5', '6'],
"VisitDate": ['1/1/2023', '2/1/2023', '3/1/2023', '4/1/2023', '5/1/2023']})
df['VisitDate'] = pd.to_datetime(df['VisitDate'])

# 定义目标时间段条件与对应标签
conditions = [
    df['VisitDate'].between('2023-01-01', '2023-02-01'),
    df['VisitDate'].between('2023-04-01', '2023-05-01')
]
labels = ['Dates: 1/1/2023 - 2/1/2023', 'Dates: 4/1/2023 - 5/1/2023']

# 生成分组列,不符合条件的标记为NaN
df['period'] = np.select(conditions, labels, default=np.nan)
# 过滤无效行并统计独立访问数
result = df.dropna(subset=['period']).groupby('period')['VisitID'].nunique()

方式二:一步到位,无需新增中间列

如果不想在DataFrame中新增列,可以直接在groupby中使用np.select,代码更紧凑:

import pandas as pd
import numpy as np

df = pd.DataFrame({"VisitID":['1', '2', '4', '5', '6'],
"VisitDate": ['1/1/2023', '2/1/2023', '3/1/2023', '4/1/2023', '5/1/2023']})
df['VisitDate'] = pd.to_datetime(df['VisitDate'])

result = df.groupby(
    np.select(
        [
            df['VisitDate'].between('2023-01-01', '2023-02-01'),
            df['VisitDate'].between('2023-04-01', '2023-05-01')
        ],
        ['Dates: 1/1/2023 - 2/1/2023', 'Dates: 4/1/2023 - 5/1/2023'],
        default=np.nan
    )
)['VisitID'].nunique().dropna()

优化说明

这两种方式都去掉了原代码中冗余的分类标签和后续过滤步骤,直接聚焦于需要统计的时间段,代码逻辑更直观,也更符合Pythonic的简洁风格。

内容的提问来源于stack exchange,提问作者Yisroel Len

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 17:41:01