【问题标题】:count values of groups by consecutive days按连续天数计算组的值
【发布时间】:2021-11-07 00:51:23
【问题描述】:

我有 3 列的数据:日期、ID、销售额。 我的第一个任务是过滤超过 100 的销售额。我做到了。 第二个任务,按连续天数对 id 进行分组。

index date id sales
0 01/01/2018 03 101
1 01/01/2018 07 178
2 02/01/2018 03 120
3 03/01/2018 03 150
4 05/01/2018 07 205

结果应该是:

index id count
0 03 3
1 07 1
2 07 1

我需要在不使用 pandas/dataframe 的情况下完成这项任务,但现在我无法想象从哪方面攻击这个问题。 只是为了努力,我在这里尝试了解决方案的建议count consecutive days python dataframe 但 id 没有分组。 这是我的代码:

data = df[df['sales'] >= 100]
data['date'] = pd.to_datetime(data['date']).dt.date
s = data.groupby('id').date.diff().dt.days.ne(1).cumsum()
new_frame = data.groupby(['id', s]).size().reset_index(level=0, drop=True)

“new_frame”将具有“count”列是非常重要的,因为在我需要按“count”列中的那些计数天数的范围计算 id 之后。例如id 的计数在 0-7 天、7-12 天等范围内,但这不是我的问题的一部分。 非常感谢

【问题讨论】:

    标签: python pandas list dataframe grouping


    【解决方案1】:

    你的代码很接近,但需要一些微调,如下:

    data = df[df['sales'] >= 100]
    data['date'] = pd.to_datetime(data['date'], dayfirst=True)
    
    df2 = data.sort_values(['id', 'date'])
    s = df2.groupby('id').date.diff().dt.days.ne(1).cumsum()
    new_frame = df2.groupby(['id', s]).size().reset_index(level=1, drop=True).reset_index(name='count')
    

    结果:

    print(new_frame)
    
       id  count
    0   3      3
    1   7      1
    2   7      1
    

    变更摘要:

    1. 由于您的日期在dd/mm/yyyy 而不是默认的mm/dd/yyyy,因此您必须在pd.to_datetime() 中指定参数dayfirst=True。否则,02/01/2018 将被视为2018-02-01 而不是预期的2018-01-02,并且与相邻条目的日期差异将在 30 左右而不是 1。

    2. 我们添加了一个排序步骤来按列iddate 进行排序,以简化后面在创建系列s 期间的分组。

    3. 在最后的groupby() 代码reset_index(level=0, drop=True) 应该删除level=1。因为,level=0 是我们想要保留的 id 字段。

    4. 在最后一个 groupby() 中,我们额外添加了一个 .reset_index(name='count') 以使 Pandas 系列变回数据框,并将新列命名为 count

    【讨论】:

    • SeaBean 你真是个天才,非常感谢。您能否向我解释一下需要 ne(1) 函数,该函数在该行中的目的是什么?谢谢
    • @paul .ne() 是测试not equal 的函数,即!=ne(1) 用于测试 2 个连续条目之间的日期差异不等于 1。由于您在日期差大于 1 时需要一个新组,因此我们使用此测试,以便只要条件为真(即日期差 > 1),.cumsum() 函数就会生成一个新组号。
    • @paul 请注意,您基于的解决方案是将连续天 not equal 检查为 1 以生成新组(因此是新计数)。请注意您的数据中日期差异可能为0 的可能性。在这种情况下,差异为 0,这也是 ne(1)。所以,看看是不是你想要的。您也可以考虑将其更改为gt(1) 严格> 1。
    猜你喜欢
    • 2020-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-08
    • 1970-01-01
    • 2023-03-25
    • 2020-01-23
    相关资源
    最近更新 更多