【问题标题】:establish begin/end dates via groupby通过 groupby 建立开始/结束日期
【发布时间】:2015-11-28 23:52:20
【问题描述】:

我正在尝试找到一种干净的 Python/Pandas 方法来获取以下数据框:

ID  Date_Field Category 
12345 01/01/12 AAAA
12345 01/02/12 AAAA
12345 01/03/12 AAAA
12345 01/04/12 BBBB
12345 01/05/12 BBBB
12345 01/06/12 BBBB
2468  01/01/12 AAAA
2468  01/02/12 AAAA
2468  01/03/12 AAAA
2468  01/04/12 BBBB
2468  01/05/12 BBBB
2468  01/06/12 BBBB
2468  01/07/12 BBBB
2468  01/08/12 CCCC
2468  01/09/12 CCCC
2468  01/10/12 AAAA
2468  01/11/12 AAAA

并将其转换为与此类似的数据框,即,我有每个 ID/类别的开始/结束日期,但需要注意的是,如果两者之间存在日期差距,ID/类别组合可能会出现多次:

ID  Start_Date End_Date Category
12345 01/01/12 01/03/12 AAAA
12345 01/04/12 01/06/12 BBBB
2468  01/01/12 01/03/12 AAAA
2468  01/10/12 01/11/12 AAAA
2468  01/04/12 01/07/12 BBBB
2468  01/08/12 01/09/12 CCCC

我知道我可以通过迭代和与之前的行值进行比较来做到这一点,但我觉得有一种更清洁的方法。

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:

    您可以发送groupby。如果你只想要一列,你可以这样做:

    >>> df.groupby(['ID','Category']).min()
    
                   Date_Field
    ID    Category           
    2468  AAAA       01/01/12
          BBBB       01/04/12
          CCCC       01/08/12
    12345 AAAA       01/01/12
          BBBB       01/04/12
    

    你也可以做到最大,就像this answer

    >>> df.groupby(['ID','Category']).agg({'Date_Field' : [min, max]})
    
                   Date_Field          
                          min       max
    ID    Category                     
    2468  AAAA       01/01/12  01/11/12
          BBBB       01/04/12  01/07/12
          CCCC       01/08/12  01/09/12
    12345 AAAA       01/01/12  01/03/12
          BBBB       01/04/12  01/06/12
    


    编辑:

    groupby 会导致 DataFramegrouped columns as index,禁用此添加 as_index=False

    >>> df.groupby(['ID','Category'], as_index=False).agg({'Date_Field' : [min, max]})
    
          ID Category Date_Field          
                             min       max
    0   2468     AAAA   01/01/12  01/11/12
    1   2468     BBBB   01/04/12  01/07/12
    2   2468     CCCC   01/08/12  01/09/12
    3  12345     AAAA   01/01/12  01/03/12
    4  12345     BBBB   01/04/12  01/06/12
    


    编辑 2

    要分隔具有相同 ID 和类别的数据的不同时间间隔,我们必须添加一个新类别:

    df['Cat2']=0
    for i in range(2,len(df)):
       if df['Category'].iloc[i]==df['Category'][i-1]:
         df['Cat2'].iloc[i]=df['Cat2'].iloc[i-1]
       else:
         df['Cat2'].iloc[i]=df['Cat2'].iloc[i-1]+1
    

    这个 for 循环创建一个新的 Cat2 列,如果前一行 (i-1) 具有相同的 Category,则该列将具有相同的值,否则创建一个新值 (previous+1)。请注意,此方法完全取决于数据的顺序! 现在我们可以将其添加到groupby 类别中:

     >>> df.groupby(['ID','Category','Cat2'], as_index=False).agg({'Date_Field' : [min, max]})
    
          ID Category Cat2 Date_Field          
                                  min       max
    0   2468     AAAA    2   01/01/12  01/03/12
    1   2468     AAAA    5   01/10/12  01/11/12
    2   2468     BBBB    3   01/04/12  01/07/12
    3   2468     CCCC    4   01/08/12  01/09/12
    4  12345     AAAA    0   01/01/12  01/03/12
    5  12345     BBBB    1   01/04/12  01/06/12
    

    【讨论】:

    • 谢谢!这很好 - 一个基本问题,我怎样才能利用它来制作一个前向填充的数据框?
    • 实际上结果是一个DataFrame,但检查我的编辑。
    • 实际上是一个问题 - 预期结果应该有两个条目,分别是 2468 和 AAAA,因为有 2 个时间间隔。
    • 再次感谢。我将逐步使用调试器来更好地理解这一点。这是非常好的!
    猜你喜欢
    • 1970-01-01
    • 2012-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多