【问题标题】:Pandas - Identify Last Row by DatePandas - 按日期识别最后一行
【发布时间】:2017-03-24 21:52:40
【问题描述】:

我试图在我的 Pandas 数据框中完成两件事:

  1. 根据新的 DateCompleted 创建新列 Last Row(“是”或“否”)
  2. 捕获当前行的下一个事务,除非它是新的 DateCompleted(在这种情况下标记为 Null)。

原始数据集

        DateCompleted      TranNumber  Sales

    0   1/1/17 10:15AM     3133         130.31
    1   1/1/17 11:21AM     3531         103.12  
    2   1/1/17 12:31PM     3652         99.23  
    3   1/2/17 9:31AM      3689         83.22
    4   1/2/17 10:31AM     3701         29.93
    5   1/3/17 8:30AM      3709         31.31 

期望的输出

        DateCompleted      TranNumber   Sales    NextTranSales  LastRow

    0   1/1/17 10:15AM     3133         130.31   103.12         No
    1   1/1/17 11:21AM     3531         103.12   99.23          No
    2   1/1/17 12:31PM     3652         99.23    NaN            Yes
    3   1/2/17 9:31AM      3689         83.22    29.93          No 
    4   1/2/17 10:31AM     3701         29.93    NaN            Yes
    5   1/3/17 8:30AM      3709         31.31    ...            No

我可以根据以下条件获取 NextTranSales:

 df['NextTranSales'] = df.Sales.shift(-1)

但我在确定 DateCompleted 组中的最后一行并将 NextTranSales 标记为 Null(如果它是最后一行)时遇到了问题。

感谢您的帮助!

【问题讨论】:

    标签: python pandas group-by shift


    【解决方案1】:

    如果您的数据框已按 DateCompleted 列排序,那么您可能只需要groupby.shift

    date = pd.to_datetime(df.DateCompleted).dt.date    
    df["NextTranSales"] = df.groupby(date).Sales.shift(-1)
    

    如果您需要LastRow 列,可以使用groupby 找出最后一行索引,然后将yes 分配给行:

    last_row_index = df.groupby(date, as_index=False).apply(lambda g: g.index[-1])
    df["LastRow"] = "No"
    df.loc[last_row_index, "LastRow"] = "Yes"
    df
    

    【讨论】:

      【解决方案2】:

      注意: 这取决于Sales 没有NaN。如果它有任何NaN,我们将得到最后一行的错误确定。发生这种情况是因为我利用了移位列在最后一个位置留下NaN 的便利性。

      d = df.DateCompleted.dt.date
      m = {True: 'Yes', False: 'No'}
      s = df.groupby(d).Sales.shift(-1)
      df = df.assign(NextTranSales=s).assign(LastRow=s.isnull().map(m))
      print(df)
      
              DateCompleted  TranNumber   Sales  NextTranSales LastRow
      0 2017-01-01 10:15:00        3133  130.31         103.12      No
      1 2017-01-01 11:21:00        3531  103.12          99.23      No
      2 2017-01-01 12:31:00        3652   99.23            NaN     Yes
      3 2017-01-02 09:31:00        3689   83.22          29.93      No
      4 2017-01-02 10:31:00        3701   29.93            NaN     Yes
      5 2017-01-03 08:30:00        3709   31.31            NaN     Yes
      

      有了这个,我们就可以摆脱no NaN的限制

      d = df.DateCompleted.dt.date
      m = {True: 'Yes', False: 'No'}
      s = df.groupby(d).Sales.shift(-1)
      l = pd.Series(
          'Yes', df.groupby(d).tail(1).index
      ).reindex(df.index, fill_value='No')
      df.assign(NextTranSales=s).assign(LastRow=l)
      
              DateCompleted  TranNumber   Sales  NextTranSales LastRow
      0 2017-01-01 10:15:00        3133  130.31         103.12      No
      1 2017-01-01 11:21:00        3531  103.12          99.23      No
      2 2017-01-01 12:31:00        3652   99.23            NaN     Yes
      3 2017-01-02 09:31:00        3689   83.22          29.93      No
      4 2017-01-02 10:31:00        3701   29.93            NaN     Yes
      5 2017-01-03 08:30:00        3709   31.31            NaN     Yes
      

      【讨论】:

      • 效果很好!再次感谢您帮助我——您本周早些时候提供了帮助 :)
      猜你喜欢
      • 2012-12-10
      • 1970-01-01
      • 1970-01-01
      • 2021-09-15
      • 2020-12-28
      • 2019-04-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多