在groupby数据框(Python)中查找给定日期的最近日期
我试图在pandas数据框中生成在groupby数据框(Python)中查找给定日期的最近日期,python,datetime,group-by,Python,Datetime,Group By,我试图在pandas数据框中生成上次付款日期字段,并且需要为每个客户(即groupby)找到给定的订单日期之前最近的付款日期 付款日期总是发生在订单日期之后,但可能需要不同的时间段,这很难使用排序和移位来查找最近的日期 这似乎是一种可行的方法,但我还没有找到一种方法来使用它 感谢所有能给我的帮助 Cust_No Order_Date Payment_Date Last_Payment_Date A 5/8/2014 6/8/2014
上次付款日期
字段,并且需要为每个客户(即groupby)找到给定的订单日期
之前最近的付款日期
付款日期
总是发生在订单日期
之后,但可能需要不同的时间段,这很难使用排序和移位来查找最近的日期
这似乎是一种可行的方法,但我还没有找到一种方法来使用它
感谢所有能给我的帮助
Cust_No Order_Date Payment_Date Last_Payment_Date
A 5/8/2014 6/8/2014 Nat
B 6/8/2014 1/5/2015 Nat
B 7/8/2014 7/8/2014 Nat
A 8/8/2014 1/5/2015 6/8/2014
A 9/8/2014 10/8/2014 6/8/2014
A 10/11/2014 12/11/2014 10/8/2014
B 11/12/2014 1/1/2015 7/8/2014
B 1/2/2015 2/2/2015 1/1/2015
A 2/5/2015 5/5/2015 1/5/2015
B 3/5/2015 4/5/2015 2/2/2015
基本上就是你想要的——它
可用于查找Order\u Date
s在Payment\u Date
s中的位置。在里面
特别是,它返回与每个
需要插入订单日期
,以保留付款日期
分类。例如,假设
In [266]: df['Payment_Date']
Out[266]:
0 2014-06-08
2 2014-07-08
4 2014-10-08
5 2014-12-11
6 2015-01-01
1 2015-01-05
3 2015-01-05
7 2015-02-02
9 2015-04-05
8 2015-05-05
Name: Payment_Date, dtype: datetime64[ns]
In [267]: df['Order_Date']
Out[267]:
0 2014-05-08
2 2014-07-08
4 2014-09-08
5 2014-10-11
6 2014-11-12
1 2014-06-08
3 2014-08-08
7 2015-01-02
9 2015-03-05
8 2015-02-05
Name: Order_Date, dtype: datetime64[ns]
然后searchsorted
返回
In [268]: df['Payment_Date'].searchsorted(df['Order_Date'])
Out[268]: array([0, 1, 2, 3, 3, 0, 2, 5, 8, 8])
例如,第一个值0表示订单日期,2014-05-08
,
必须在序号索引0处插入(在付款日期之前
2014-06-08
)以保持付款日期的排序。第二个值,1,
指示必须在以下位置插入订单日期,2014-07-08
顺序索引1(在付款日期之后和之前)
保持付款日期的排序。其他指数也是如此
当然,现在有一些复杂情况:
付款日期
需要按排序顺序进行排序,以便搜索排序
返回
有意义的结果:
df = df.sort_values(by=['Payment_Date'])
grouped = df.groupby('Cust_No')
索引
订单日期
。因此,我们确实需要将指数减少1:
idx = grp['Payment_Date'].searchsorted(grp['Order_Date'])
result = grp['Payment_Date'].iloc[idx-1]
grp['Payment\u Date'].iloc[idx-1]
将获取先前的Payment\u Date
searchsorted
返回0时,Order\u Date
小于all
付款日期
s。在这种情况下我们需要NaT
result[idx == 0] = pd.NaT
所以把这一切放在一起
import pandas as pd
NaT = pd.NaT
T = pd.Timestamp
df = pd.DataFrame({
'Cust_No': ['A', 'B', 'B', 'A', 'A', 'A', 'B', 'B', 'A', 'B'],
'expected': [
NaT, NaT, NaT, T('2014-06-08'), T('2014-06-08'), T('2014-10-08'),
T('2014-07-08'), T('2015-01-01'), T('2015-01-05'), T('2015-02-02')],
'Order_Date': [
T('2014-05-08'), T('2014-06-08'), T('2014-07-08'), T('2014-08-08'),
T('2014-09-08'), T('2014-10-11'), T('2014-11-12'), T('2015-01-02'),
T('2015-02-05'), T('2015-03-05')],
'Payment_Date': [
T('2014-06-08'), T('2015-01-05'), T('2014-07-08'), T('2015-01-05'),
T('2014-10-08'), T('2014-12-11'), T('2015-01-01'), T('2015-02-02'),
T('2015-05-05'), T('2015-04-05')]})
def last_payment_date(s, df):
grp = df.loc[s.index]
idx = grp['Payment_Date'].searchsorted(grp['Order_Date'])
result = grp['Payment_Date'].iloc[idx-1]
result[idx == 0] = pd.NaT
return result
df = df.sort_values(by=['Payment_Date'])
grouped = df.groupby('Cust_No')
df['Last_Payment_Date'] = grouped['Payment_Date'].transform(last_payment_date, df)
print(df)
屈服
Cust_No Order_Date Payment_Date expected Last_Payment_Date
0 A 2014-05-08 2014-06-08 NaT NaT
2 B 2014-07-08 2014-07-08 NaT NaT
4 A 2014-09-08 2014-10-08 2014-06-08 2014-06-08
5 A 2014-10-11 2014-12-11 2014-10-08 2014-10-08
6 B 2014-11-12 2015-01-01 2014-07-08 2014-07-08
1 B 2014-06-08 2015-01-05 NaT NaT
3 A 2014-08-08 2015-01-05 2014-06-08 2014-06-08
7 B 2015-01-02 2015-02-02 2015-01-01 2015-01-01
9 B 2015-03-05 2015-04-05 2015-02-02 2015-02-02
8 A 2015-02-05 2015-05-05 2015-01-05 2015-01-05
付款日期
是否总是在下一个订单日期
之前?否,如客户B的前两个记录所示。如果找不到以前的付款日期,则应反映Nat。谢谢在尝试回答我自己的问题时,您能否再次检查您为上次付款日期提供的列是否100%正确?有些日期不匹配(2015年2月5日vs 2015年2月2日),我想确保我会给你你想要的。我对拼写错误感到非常抱歉!我已经改正了。