[英]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.