gpt4 book ai didi

python - 跨 DataFrame 减去日期

转载 作者:太空宇宙 更新时间:2023-11-03 15:35:14 25 4
gpt4 key购买 nike

我刚刚开始学习 Python 和 R,因此非常感谢任何使用它们的建议。

我的数据存储在两个数据框中。一个是销售数据,对于每个消费者,我们可以看到他购买东西的日期。同一个人可能多次购买:

Date             Person ID      Product       
01-05-2012 1 cereal
01-05-2012 2 apple
02-08-2012 3 beef
03-22-2013 72 pot
07-19-2012 1 cake

第二个 dataframe 有成员(member)数据,它告诉我们一个人是什么时候加入这个项目的:

Date             Person ID      Type      Status      
06-11-2008 1 Gold New
10-12-2011 2 Gold New
02-08-2011 3 Silver Renewal
02-01-2012 72 Gold Renewal
03-22-2012 1 Gold Renewal

我想做的是,对于同一个人,一个人在他注册一个程序之前需要多长时间才能购买东西。

例如,第 1 个人在 06-11-2008 获得了新成员(member)资格并在 01-05-2012 购买了麦片。我想计算这两个日期之间有多少天。

但是,这些信息存储在单独的数据框中。我不认为它们可以附加或合并到一个数据框中,因为一个人可以在一个或两个数据框中拥有多个观察值。

我的想法是,从销售数据中提取所有日期,并从许可证数据中提取所有日期。然后将这两个新的数据框合并成一个新的数据框。这将给我:

License Date     Person ID      Sales Date            
06-11-2008 1 01-05-2012
10-12-2011 2 01-05-2012
02-08-2011 3 02-08-2011
02-01-2012 72 03-22-2013
06-11-2008 1 07-19-2012
03-22-2012 1 01-05-2012
03-22-2012 1 07-19-2012

但这里的问题是,如果一个人有两个许可证日期(例如一个新的和一个更新的),那么合并数据将给出 2*(销售日期)...但我只想要一个销售日期有效的许可证..

例如,人 1 使用许可证 06-11-2008 在 01-05-2012 购买麦片,并使用许可证 03-22-2012 在 07-19-2012 购买。但是合并数据框会给我 4 条记录,而不是我想要的 2 条...

我想要的结果是每次销售的购买时间,在他获得用于该次购买的许可证之后:

License Date     Person ID      Sales Date   TimeToPurchase         
06-11-2008 1 01-05-2012 ...
10-12-2011 2 01-05-2012 ...
02-08-2011 3 02-08-2011 ...
02-01-2012 72 03-22-2013 ...
03-22-2012 1 07-19-2012 ...

你有没有更好的方法建议我做?

非常感谢您的帮助!

最佳答案

Pandas

首先你的日期需要保存为日期时间,你可以这样完成:

sales['Date'] = pd.to_datetime(sales['Date'])
memberships['Date'] = pd.to_datetime(memberships['Date'])

然后您通过Person ID 合并它们并得到有重复的格式。

m = sales.merge(memberships, left_on='Person ID', right_on='Person ID',
suffixes=('_sales', '_memberships'))
m

Date_sales Person ID Product Date_memberships Type Status
0 2012-01-05 1 cereal 2008-06-11 Gold New
1 2012-01-05 1 cereal 2012-03-22 Gold Renewal
2 2012-07-19 1 cake 2008-06-11 Gold New
3 2012-07-19 1 cake 2012-03-22 Gold Renewal
4 2012-01-05 2 apple 2011-10-12 Gold New
5 2012-02-08 3 beef 2011-02-08 Silver Renewal
6 2013-03-22 72 pot 2012-02-01 Gold Renewal

现在您可以像这样计算销售日期和成员(member)日期之间经过的天数:

m['TimeToPurchase'] = (m['Date_sales'] - m['Date_memberships']).dt.days
m

Date_sales Person ID Product Date_memberships Type Status TimeToPurchase
0 2012-01-05 1 cereal 2008-06-11 Gold New 1303
1 2012-01-05 1 cereal 2012-03-22 Gold Renewal -77
2 2012-07-19 1 cake 2008-06-11 Gold New 1499
3 2012-07-19 1 cake 2012-03-22 Gold Renewal 119
4 2012-01-05 2 apple 2011-10-12 Gold New 85
5 2012-02-08 3 beef 2011-02-08 Silver Renewal 365
6 2013-03-22 72 pot 2012-02-01 Gold Renewal 415

从这里您可以首先消除负数,然后获得每个 Person ID 和 Date 销售的最小 TimeToPurchase

m = m[m['TimeToPurchase'] >= 0]
keep = m.groupby(['Person ID', 'Date_sales'], as_index=False)['TimeToPurchase'].min()
keep

Person ID Date_sales TimeToPurchase
1 2012-01-05 1303
1 2012-07-19 119
2 2012-01-05 85
3 2012-02-08 365
72 2013-03-22 415

这些是您要保留在合并表中的记录,您可以使用内部联接对其进行过滤:

result = m.merge(keep, 
left_on=['Person ID', 'Date_sales', 'TimeToPurchase'],
right_on=['Person ID', 'Date_sales', 'TimeToPurchase'])
result

Date_sales Person ID Product Date_memberships Type Status TimeToPurchase
2012-01-05 1 cereal 2008-06-11 Gold New 1303
2012-07-19 1 cake 2012-03-22 Gold Renewal 119
2012-01-05 2 apple 2011-10-12 Gold New 85
2012-02-08 3 beef 2011-02-08 Silver Renewal 365
2013-03-22 72 pot 2012-02-01 Gold Renewal 415

数据表

和上面的逻辑一样,所以我就直接贴代码吧。

# Date types
sales[, Date := as.Date(Date, format = "%m-%d-%Y")]
memberships[, Date := as.Date(Date, format = "%m-%d-%Y")]

# Merge
m <- memberships[sales, on = "Person ID"]

# Calculate elapsed days
m[, TimeToPurchase := as.numeric(m$i.Date - m$Date)]

# Eliminate negatives
m <- m[TimeToPurchase >= 0]

# Calculate records to keep
keep <- m[, .(TimeToPurchase = min(TimeToPurchase)), by = .(`Person ID`, i.Date)]

# Filter result
result <- m[keep, on = c("Person ID", "i.Date", "TimeToPurchase")]
result

Date Person ID Type Status i.Date Product TimeToPurchase
1: 2008-06-11 1 Gold New 2012-01-05 cereal 1303
2: 2011-10-12 2 Gold New 2012-01-05 apple 85
3: 2011-02-08 3 Silver Renewal 2012-02-08 beef 365
4: 2012-02-01 72 Gold Renewal 2013-03-22 pot 415
5: 2012-03-22 1 Gold Renewal 2012-07-19 cake 119

关于python - 跨 DataFrame 减去日期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55185867/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com