熊猫 - 按日期确定最后一行

时间:2017-03-24 21:52:41

标签: python pandas group-by shift

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

  1. 根据新的DateCompleted
  2. 创建新列最后一行('是'或'否')
  3. 捕获当前行的下一个事务,除非它是一个新的DateCompleted(在这种情况下标记为Null)。
  4. 原始数据集

            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。

    感谢您的帮助!

2 个答案:

答案 0 :(得分:4)

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

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

enter image description here

如果您需要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

enter image description here

答案 1 :(得分: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

我们可以免除 没有 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