反向累积以逐月获取熊猫中的数据

时间:2018-09-12 09:22:30

标签: python excel pandas

我收到了带有累积数字的数据。是否有一种聪明的方法可以逆转数据的累积,所以我每个月都有它,而不是彼此堆叠?

示例输入:

 Date    SalesRep    itemA   
 01-12-2017  X        1      
 01-12-2017  Y        0     
 01-12-2017  Z        0   
 01-01-2018  X        1     
 01-01-2018  Y        1     
 01-01-2018  Z        0    
 01-02-2018  X        1    
 01-02-2018  Y        1    
 01-02-2018  Z        1   

所需的输出:

 Date    SalesRep    itemA   
 01-12-2017  X       1      
 01-12-2017  Y       0     
 01-12-2017  Z       0   
 01-01-2018  X       0     
 01-01-2018  Y       1     
 01-01-2018  Z       0    
 01-02-2018  X       0   
 01-02-2018  Y       0    
 01-02-2018  Z       1  

我正在使用从论坛重用的脚本。

import pandas as pd
df = pd.read_excel('File.xlsx')

df['Date'] = pd.to_datetime(df['Date'], dayfirst=True)

df = df.sort_values('Date', ascending=False) # This now sorts in date order

cum_columns = ['itemA']

result = df.merge(
df.groupby('SalesRep')[cum_columns].diff(),
left_index=True, right_index=True, suffixes=['', '_uncum']
).fillna({'{}_uncum'.format(cum_column): df[cum_column] for cum_column in cum_columns})

print(result)

由于在最后一个月中每个值都是1,所以其余月份是0。如何更改脚本以适合我的情况?

编辑

使用JohnE回答我遇到错误,请看一下:

    Date              SalesRep  ItemA   itemA_diff
    2018-08-01 00:00:00 John    1        1
    2018-07-01 00:00:00 John    1        0
    2018-06-01 00:00:00 John    0        -1
    2018-05-01 00:00:00 John    0        0
    2018-04-01 00:00:00 John    0        0
    2018-03-01 00:00:00 John    0        0
    2018-02-01 00:00:00 John    0        0
    2018-01-01 00:00:00 John    0        0
    2017-12-01 00:00:00 John    0        0
    2017-11-01 00:00:00 John    0        0
    2017-10-01 00:00:00 John    0        0

我应该得到

    Date              SalesRep  ItemA   itemA_diff
    2018-08-01 00:00:00 John    1        0
    2018-07-01 00:00:00 John    1        1
    2018-06-01 00:00:00 John    0        0
    2018-05-01 00:00:00 John    0        0
    2018-04-01 00:00:00 John    0        0
    2018-03-01 00:00:00 John    0        0
    2018-02-01 00:00:00 John    0        0
    2018-01-01 00:00:00 John    0        0
    2017-12-01 00:00:00 John    0        0
    2017-11-01 00:00:00 John    0        0
    2017-10-01 00:00:00 John    0        0

应该更改什么?

1 个答案:

答案 0 :(得分:1)

这是结合groupbydiff的相当标准的用例,尽管语法可能相当精细(请参见下面的注释):

df = df.sort_values('Date')
df['itemA_diff'] = df.groupby('SalesRep')['itemA'].diff()
df['itemA_diff'] = df['itemA_diff'].fillna(df['itemA'])

结果:

        Date SalesRep  itemA  itemA_diff
0 2017-01-12        X      1         1.0
1 2017-01-12        Y      0         0.0
2 2017-01-12        Z      0         0.0
3 2018-01-01        X      1         0.0
4 2018-01-01        Y      1         1.0
5 2018-01-01        Z      0         0.0
6 2018-01-02        X      1         0.0
7 2018-01-02        Y      1         0.0
8 2018-01-02        Z      1         1.0

注意:

  1. 重要的是要首先按“日期”进行排序,并且还根据需要使用pd.to_datetime将其转换为正确的熊猫日期时间。

  2. 我不确定为什么,但是“ Date”和“ itemA”都必须是列而不是索引。 (我在尝试使用索引中的“日期”时遇到了奇怪的错误)

替代方法:以下是@jezrael要求提供的原始答案,因为它可能会更快:

df = df.sort_values(['SalesRep','Date'])
df['itemA_diff'] = df['itemA'].diff()
df['itemA_diff'] = np.where( df.SalesRep == df.shift().SalesRep, 
                             df.itemA_diff, 
                             df.itemA )