Sql 熊猫:获取分组和条件化的最后一个值
在以下数据集中(作为字典-使用Sql 熊猫:获取分组和条件化的最后一个值,sql,pandas,pandas-groupby,Sql,Pandas,Pandas Groupby,在以下数据集中(作为字典-使用pd.DataFrame.from_dict) 对于每个客户(Customer\u id),获取上个月(t-1)中逾期天数==7。此外,我还需要获得2个月前拖欠的值(t-2)其中到期后天数==30,,用于我的数据集中的每一行 customer_id binned_due_date days_after_due_date delinquency 0 33179018 2020-01-01 0
pd.DataFrame.from_dict
)
对于每个客户(Customer\u id
),获取上个月(t-1)
中逾期天数==7
。此外,我还需要获得2个月前拖欠的值(t-2)
其中到期后天数==30
,,用于我的数据集中的每一行
customer_id binned_due_date days_after_due_date delinquency
0 33179018 2020-01-01 0 0.286724
1 33179018 2020-01-01 7 0.211174
2 33179018 2020-01-01 15 0.140371
3 33179018 2020-01-01 30 0.015999
4 33179018 2020-01-01 45 0.011409
5 33179018 2020-01-01 60 0.011409
6 33179018 2020-01-01 90 0.011409
7 33179018 2020-01-01 120 0.009632
8 33179018 2020-01-01 150 0.007854
9 33179018 2020-01-01 180 0.007854
10 33179018 2020-02-01 0 0.094125
11 33179018 2020-02-01 7 0.082343
12 33179018 2020-02-01 15 0.065993
13 33179018 2020-02-01 30 0.041558
14 33179018 2020-02-01 45 0.041558
15 33179018 2020-02-01 60 0.041558
16 33179018 2020-02-01 90 0.038385
17 33179018 2020-02-01 120 0.035212
18 33179018 2020-02-01 150 0.035212
19 33179018 2020-02-01 180 0.028058
20 33179018 2020-03-01 0 0.089591
21 33179018 2020-03-01 7 0.085447
22 33179018 2020-03-01 15 0.071879
23 33179018 2020-03-01 30 0.066374
24 33179018 2020-03-01 45 0.061330
25 33179018 2020-03-01 60 0.048050
26 33179018 2020-03-01 90 0.042426
27 33179018 2020-03-01 120 0.042426
28 33179018 2020-03-01 150 0.035591
29 33179018 2020-03-01 180 0.035591
在SQL中,我们尝试了以下方法,但并不完全按照我描述的方式工作,对我来说,最好使用Pandas
最后一个值(如果(到期日后的天数=7,拖欠,空)忽略空值)超过(
按observed.customer\u id按observed.bined\u due\u date、observed.days\u due\u date行在无界的前一行和前一行之间划分最后一行7,
所需的输出将是(由@Umar.h请求):
不确定是否有更好的方法,但这里有一个:
>>> df['d7 t-1'] = df.query('days_after_due_date == [7]')[['delinquency']].shift(1)
>>> df['d30 t-2'] = df.query('days_after_due_date == [30]')[['delinquency']].shift(1)
>>> df.ffill().fillna('-')
customer_id binned_due_date days_after_due_date delinquency d7 t-1 d30 t-2
0 33179018 2020-01-01 0 0.286724 - -
1 33179018 2020-01-01 7 0.211174 - -
2 33179018 2020-01-01 15 0.140371 - -
3 33179018 2020-01-01 30 0.015999 - -
4 33179018 2020-01-01 45 0.011409 - -
5 33179018 2020-01-01 60 0.011409 - -
6 33179018 2020-01-01 90 0.011409 - -
7 33179018 2020-01-01 120 0.009632 - -
8 33179018 2020-01-01 150 0.007854 - -
9 33179018 2020-01-01 180 0.007854 - -
10 33179018 2020-02-01 0 0.094125 - -
11 33179018 2020-02-01 7 0.082343 0.211174 -
12 33179018 2020-02-01 15 0.065993 0.211174 -
13 33179018 2020-02-01 30 0.041558 0.211174 0.0159991
14 33179018 2020-02-01 45 0.041558 0.211174 0.0159991
15 33179018 2020-02-01 60 0.041558 0.211174 0.0159991
16 33179018 2020-02-01 90 0.038385 0.211174 0.0159991
17 33179018 2020-02-01 120 0.035212 0.211174 0.0159991
18 33179018 2020-02-01 150 0.035212 0.211174 0.0159991
19 33179018 2020-02-01 180 0.028058 0.211174 0.0159991
20 33179018 2020-03-01 0 0.089591 0.211174 0.0159991
21 33179018 2020-03-01 7 0.085447 0.0823426 0.0159991
22 33179018 2020-03-01 15 0.071879 0.0823426 0.0159991
23 33179018 2020-03-01 30 0.066374 0.0823426 0.0415581
24 33179018 2020-03-01 45 0.061330 0.0823426 0.0415581
25 33179018 2020-03-01 60 0.048050 0.0823426 0.0415581
26 33179018 2020-03-01 90 0.042426 0.0823426 0.0415581
27 33179018 2020-03-01 120 0.042426 0.0823426 0.0415581
28 33179018 2020-03-01 150 0.035591 0.0823426 0.0415581
29 33179018 2020-03-01 180 0.035591 0.0823426 0.0415581
方法
解释
- 查询数据框以选择到期日后
days\u
为7
的行,让我们调用此数据框t1
- 将
1
月的日期偏移量添加到bined_due_date
列中,以便我们能够将当月的拖欠值映射到下个月
- 以类似的方式,生成另一个数据帧
t2
,以便我们能够将当前月份的拖欠值映射到之后的两个月
- 根据通用的
“客户id”和和到期日,将拖欠值从t1
和t2
映射到给定的数据帧
结果
注意:数据必须已经在Customer、DueDate、DaysAfterDueDate顺序中。您可以添加输出吗?这应该可以为您回答大多数问题:(对于执行完整逻辑的实际代码,您应该包括您想要的结果,而不仅仅是您开始时的数据)对不起,刚刚更新,因为我忘了在@matbailee添加它,但是这个方法不能用于groupby('customer\u id')
对不起,我一定是误解了。。。提供的解决方案与您所需的输出完全匹配。我不知道有不同的客户ID(至少在您的示例中没有提供)。不过,您可以使用groupby
轻松完成类似的操作。现在我需要去,但稍后会提供一些信息。这些结果显然与OP发布的结果不符。在OP中,d7_t-1
应该在第10行有一个值,d30 t-2
应该从第20行开始,而不是第13行。啊,你说得对。我已经匆匆忙忙地写了这篇文章,因为我不得不出去发表。我看到现在提供了其他解决方案,所以我可能会删除我的答案。
>>> df['d7 t-1'] = df.query('days_after_due_date == [7]')[['delinquency']].shift(1)
>>> df['d30 t-2'] = df.query('days_after_due_date == [30]')[['delinquency']].shift(1)
>>> df.ffill().fillna('-')
customer_id binned_due_date days_after_due_date delinquency d7 t-1 d30 t-2
0 33179018 2020-01-01 0 0.286724 - -
1 33179018 2020-01-01 7 0.211174 - -
2 33179018 2020-01-01 15 0.140371 - -
3 33179018 2020-01-01 30 0.015999 - -
4 33179018 2020-01-01 45 0.011409 - -
5 33179018 2020-01-01 60 0.011409 - -
6 33179018 2020-01-01 90 0.011409 - -
7 33179018 2020-01-01 120 0.009632 - -
8 33179018 2020-01-01 150 0.007854 - -
9 33179018 2020-01-01 180 0.007854 - -
10 33179018 2020-02-01 0 0.094125 - -
11 33179018 2020-02-01 7 0.082343 0.211174 -
12 33179018 2020-02-01 15 0.065993 0.211174 -
13 33179018 2020-02-01 30 0.041558 0.211174 0.0159991
14 33179018 2020-02-01 45 0.041558 0.211174 0.0159991
15 33179018 2020-02-01 60 0.041558 0.211174 0.0159991
16 33179018 2020-02-01 90 0.038385 0.211174 0.0159991
17 33179018 2020-02-01 120 0.035212 0.211174 0.0159991
18 33179018 2020-02-01 150 0.035212 0.211174 0.0159991
19 33179018 2020-02-01 180 0.028058 0.211174 0.0159991
20 33179018 2020-03-01 0 0.089591 0.211174 0.0159991
21 33179018 2020-03-01 7 0.085447 0.0823426 0.0159991
22 33179018 2020-03-01 15 0.071879 0.0823426 0.0159991
23 33179018 2020-03-01 30 0.066374 0.0823426 0.0415581
24 33179018 2020-03-01 45 0.061330 0.0823426 0.0415581
25 33179018 2020-03-01 60 0.048050 0.0823426 0.0415581
26 33179018 2020-03-01 90 0.042426 0.0823426 0.0415581
27 33179018 2020-03-01 120 0.042426 0.0823426 0.0415581
28 33179018 2020-03-01 150 0.035591 0.0823426 0.0415581
29 33179018 2020-03-01 180 0.035591 0.0823426 0.0415581
c = ['customer_id', 'binned_due_date']
t1 = df[df['days_after_due_date'] == 7].copy()
t1['binned_due_date'] += pd.DateOffset(months=1)
t2 = df[df['days_after_due_date'] == 30].copy()
t2['binned_due_date'] += pd.DateOffset(months=2)
df['d7 t-1'] = df.set_index(c).index.map(t1.set_index(c)['delinquency'])
df['d30 t-2'] = df.set_index(c).index.map(t2.set_index(c)['delinquency'])
customer_id binned_due_date days_after_due_date delinquency d7 t-1 d30 t-2
0 33179018 2020-01-01 0 0.286724 NaN NaN
1 33179018 2020-01-01 7 0.211174 NaN NaN
2 33179018 2020-01-01 15 0.140371 NaN NaN
3 33179018 2020-01-01 30 0.015999 NaN NaN
4 33179018 2020-01-01 45 0.011409 NaN NaN
5 33179018 2020-01-01 60 0.011409 NaN NaN
6 33179018 2020-01-01 90 0.011409 NaN NaN
7 33179018 2020-01-01 120 0.009632 NaN NaN
8 33179018 2020-01-01 150 0.007854 NaN NaN
9 33179018 2020-01-01 180 0.007854 NaN NaN
10 33179018 2020-02-01 0 0.094125 0.211174 NaN
11 33179018 2020-02-01 7 0.082343 0.211174 NaN
12 33179018 2020-02-01 15 0.065993 0.211174 NaN
13 33179018 2020-02-01 30 0.041558 0.211174 NaN
14 33179018 2020-02-01 45 0.041558 0.211174 NaN
15 33179018 2020-02-01 60 0.041558 0.211174 NaN
16 33179018 2020-02-01 90 0.038385 0.211174 NaN
17 33179018 2020-02-01 120 0.035212 0.211174 NaN
18 33179018 2020-02-01 150 0.035212 0.211174 NaN
19 33179018 2020-02-01 180 0.028058 0.211174 NaN
20 33179018 2020-03-01 0 0.089591 0.082343 0.015999
21 33179018 2020-03-01 7 0.085447 0.082343 0.015999
22 33179018 2020-03-01 15 0.071879 0.082343 0.015999
23 33179018 2020-03-01 30 0.066374 0.082343 0.015999
24 33179018 2020-03-01 45 0.061330 0.082343 0.015999
25 33179018 2020-03-01 60 0.048050 0.082343 0.015999
26 33179018 2020-03-01 90 0.042426 0.082343 0.015999
27 33179018 2020-03-01 120 0.042426 0.082343 0.015999
28 33179018 2020-03-01 150 0.035591 0.082343 0.015999
29 33179018 2020-03-01 180 0.035591 0.082343 0.015999
# One row per customer/due_date, with columns for 7 and 30 days
df_pivot = df[df['days_after_due_date'].isin([7, 30])].pivot(index=['customer_id','binned_due_date'],columns='days_after_due_date',values='delinquency').reset_index()
# Offset by one or two rows (only within the same customer)
df_pivot['7_lag_1'] = df_pivot.groupby('customer_id')[7].shift(1)
df_pivot['30_lag_2'] = df_pivot.groupby('customer_id')[30].shift(2)
# Merge back on to original set
df.merge(df_pivot, on=['customer_id','binned_due_date'], how='left')