繁体   English   中英

如何使用loc推断熊猫数据框中的结束日期

[英]How do I infer an end date in a pandas dataframe using loc

我有一个数据框中的记录列表,如下所示:

update_code中的代码代表

1:更新库存

5:从库存中移除。

Date        id        amount   update_code
20170101     Apple     39            1
20170102     Pears     21            1
20170105     Apple     13            1
20170227     Pears                   5

我想为每条记录创建一个带有日期范围的列。 例如,输出应如下所示:

Date         id        amount   update_code end_date
20170101     Apple     39            1      20170104
20170102     Pears     21            1      20170226
20170105     Apple     13            1      29990909
20170227     Pears                   5      20170227

每个日期和记录应在数据框的下一次更改之前1天结束。 因此,“ Apple”的第一个记录是从01/01/2017到01/04/2017,因为在01/05/2017有一个新的“ Apple”记录。

我试图用df loc做到这一点,但在隔离每个ID时遇到了麻烦。

到目前为止,我的代码如下(如果update_code为5,则仅推断结束日期):

def end_date(df):
    df['end_date'] = ''
    df.loc[df['update'].isin([5]), 'endDate'] = df.Date
    return df

我仍然无法弄清楚如何推断每个记录的结尾并附加日期。 谢谢!

首先,您要将Date列转换为datetime并设置一个索引以区分“ Apples”和“ Pears”的不同实例。

df.Date = pd.to_datetime(df.Date, format='%Y%m%d')

我假设您的数据框可以转换为这种形式。

df
#        Date     id  amount  update_code
#0 2017-01-01  Apple    39.0            1
#1 2017-01-02  Pears    21.0            1 
#2 2017-01-05  Apple    13.0            1        
#3 2017-02-27  Pears     NaN            5        

接下来,按项目ID分组,按日期增加的顺序排列各组,将日期向后移一排,并从每个日期减去一天:

df['end_date'] = df.groupby('id').Date.apply(lambda x: 
                                             x.shift(-1) - pd.Timedelta(1))\
                                 .reset_index(0)['Date']

此操作将创建一个新列,该列仅被部分填充:

#        Date     id  amount  update_code   end_date
#0 2017-01-01  Apple    39.0            1 2017-01-04
#1 2017-01-02  Pears    21.0            1 2017-02-26
#2 2017-01-05  Apple    13.0            1        NaT
#3 2017-02-27  Pears     NaN            5        NaT

现在,用推断的日期替换更新代码5的结束日期:

df.loc[df.update_code==5,'end_date'] = df.Date

#        Date     id  amount  update_code   end_date
#0 2017-01-01  Apple    39.0            1 2017-01-04
#1 2017-01-02  Pears    21.0            1 2017-02-26
#2 2017-01-05  Apple    13.0            1        NaT
#3 2017-02-27  Pears     NaN            5 2017-02-27

如果需要,您可以用哨兵代替最后一列中的NaT(“非一次性”):

df.end_date.fillna(pd.to_datetime('20990909', format='%Y%m%d'), inplace=True)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM