【问题标题】:Frequency of events in a week一周内的事件频率
【发布时间】:2017-07-05 10:26:11
【问题描述】:

我的数据包含包含日期时间信息的行程、每次行程的用户 ID 和行程类型(单次、圆形、伪)。

这是一个名为 All_Data 的数据样本(pandas 数据框):

HoraDTRetirada        idpass        type                                             
2016-02-17 15:36:00  39579449489   'single'  
2016-02-18 19:13:00  39579449489   'single' 
2016-02-26 09:20:00  72986744521   'pseudo' 
2016-02-27 12:11:00  72986744521   'round'  
2016-02-27 14:55:00  11533148958   'pseudo'
2016-02-28 12:27:00  72986744521   'round'
2016-02-28 16:32:00  72986744521   'round'

我想按用户统计每个类别在“一年中的一周”中重复的次数。

例如,如果同一用户的事件发生在星期一,而下一个事件发生在星期四,则同一周会发生两个事件;但是,如果一个事件发生在星期六,而下一个事件发生在下一个星期一,它们发生在不同的星期。

我正在寻找的输出将是这样的形式:

idpass        weekofyear   type      frequency
39579449489    1           'single'   2
72986744521    2           'round'    3
72986744521    2           'pseudo'   1
11533148958    2           'pseudo'   1

编辑:这个older question 解决了类似的问题,但我不知道如何使用 pandas 来解决。

【问题讨论】:

  • df 中的最后一个示例是 2 月 30 日。如果您使用标准库进行日期转换,这可能会给您带来错误。
  • 谢谢,我修好了。我出于示例目的快速修改了它,并没有关注月份。
  • 所有数据点都是同一年的吗?

标签: python python-3.x pandas anaconda


【解决方案1】:
import pandas as pd

data = {"HoraDTRetirada": ["2016-02-17 15:36:00", "2016-02-18 19:13:00", "2016-12-31 09:20:00", "2016-02-28 12:11:00",
                           "2016-02-28 14:55:00", "2016-02-29 12:27:00", "2016-02-29 16:32:00"],
        "idpass": ["39579449489", "39579449489", "72986744521", "72986744521", "11533148958", "72986744521",
                   "72986744521"],
        "type": ["single", "single", "pseudo", "round", "pseudo", "round", "round"]}
df = pd.DataFrame.from_dict(data)
print(df)
df["HoraDTRetirada"] = pd.to_datetime(df['HoraDTRetirada'])
df["week"] = df['HoraDTRetirada'].dt.strftime('%U')
k = df.groupby(["idpass", "week", "type"],as_index=False).count()
print(k)

输出:

        HoraDTRetirada       idpass    type
0  2016-02-17 15:36:00  39579449489  single
1  2016-02-18 19:13:00  39579449489  single
2  2016-12-31 09:20:00  72986744521  pseudo
3  2016-02-28 12:11:00  72986744521   round
4  2016-02-28 14:55:00  11533148958  pseudo
5  2016-02-29 12:27:00  72986744521   round
6  2016-02-29 16:32:00  72986744521   round
        idpass week    type  HoraDTRetirada
0  11533148958   09  pseudo               1
1  39579449489   07  single               2
2  72986744521   09   round               3
3  72986744521   52  pseudo               1

【讨论】:

  • 我的原始数据集的列比示例中列出的列多得多,因此这种方法最终会打印出我不想要的所有其他列。星期编号正是我想要的。谢谢你。
  • 我得到了想要的输出:All_Data.groupby(['idpass','type','week']).size()' 而不是你的最后一行。
【解决方案2】:

这就是我得到我想要的东西的方式:

已跳过建议答案中的第 1 步,因为时间戳已采用 pandas 日期时间形式。

第 2 步:为一年中的一周创建列:

df['week'] = df['HoraDTRetirada'].dt.strftime('%U')

第 3 步:按用户 ID、类型和周分组,并使用 size() 计数值

df.groupby(['idpass','type','week']).size()

【讨论】:

    【解决方案3】:

    我的建议是这样做:

    1. 确保您的时间戳是 pandas 日期时间并添加频率列

      df['HoraDTRetirada'] = pd.to_datetime(df['HoraDTRetirada'])

      df['freq'] = 1

    2. 分组计数

      res = df.groupby(['idpass', 'type', pd.Grouper(key='HoraDTRetirada', freq='1W')]).count().reset_index()

    3. 将时间转换为一年中的一周

      res['HoraDTRetirada'] = res['HoraDTRetirada'].apply(lambda x: x.week)

    最终结果如下:

    编辑:

    你是对的,在你的情况下,我们应该在第 2 步之前执行第 3 步,如果你想这样做,请记住 groupby 会改变,所以最后第 2 步将是:

    res['HoraDTRetirada'] = res['HoraDTRetirada'].apply(lambda x: x.week)
    

    第三步:

    res = df.groupby(['idpass', 'type', 'HoraDTRetirada')]).count().reset_index()
    

    这有点不同,因为“Hora”变量不再是时间,而只是一个表示一周的 int。

    【讨论】:

    • 我想按周分组,所以我认为在您的模型中,步骤 3 应该在步骤 2 之前,按周而不是日期时间分组。我尝试这样做,但出现以下错误:TypeError: Only valid with DatetimeIndex, TimedeltaIndex or PeriodIndex, but got an instance of 'Index'
    • 已更新 - 如果现在还好,请告诉我
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-26
    • 2022-11-04
    • 1970-01-01
    • 2017-05-28
    相关资源
    最近更新 更多