根据另一列中的日期和标志过滤掉行

jea*_*elj 2 python group-by dataframe pandas pandas-groupby

使用python pandas DataFrame df:

Customer | date_transaction_id    | first_flag | dollars
ABC        2015-10-11-123              Y         100
BCD        2015-03-05-872              N         150
BCD        2015-01-01-923              N         -300
ABC        2015-04-04-910              N         -100
ABC        2015-12-12-765              N         -100
Run Code Online (Sandbox Code Playgroud)

上述客户ABC在4月份归还了房产,然后在11月买了一些东西.在我的分析中,我需要开始计算他们的第一个正面交易作为他们与公司的第一笔交易.如何排除客户ABC的第一笔交易?请注意,客户端BCD不是新客户端,因此不应排除任何行.

那么如何在first_flagY 之前排除日期的交易呢?

首先,我从date_transaction_id中获取日期并将其格式化为日期字段.

df['date'] = df['date_transaction_id'].astype(str).str[:10]
df['date']= pd.to_datetime(df['date'], format='%Y-%m-%d')
Run Code Online (Sandbox Code Playgroud)

然后我会按客户和日期排序

df = df.sort_values(['Customer', 'date'], ascending=[True, False])
Run Code Online (Sandbox Code Playgroud)

但是现在我被卡住了,如何在客户端删除带有first_flagY 之前的日期的行.请注意,在标记为Y的事务之前,客户端可以有一个,没有或多个事务.

这是我要找的输出:

Customer | date       | first_flag | dollars
ABC        2015-10-11      Y         100
ABC        2015-12-12      N         -100
BCD        2015-01-01      N         -300
BCD        2015-03-05      N         150
Run Code Online (Sandbox Code Playgroud)

cs9*_*s95 5

df 

  Customer date_transaction_id first_flag  dollars
0      ABC      2015-10-11-123          Y      100
1      BCD      2015-03-05-872          N      150
2      BCD      2015-01-01-923          N     -300
3      ABC      2015-04-04-910          N     -100
4      ABC      2015-12-12-765          N     -100

df['date']= pd.to_datetime(df['date_transaction_id']\
                            .astype(str).str[:10], format='%Y-%m-%d')
df = df.sort_values(['Customer', 'date'])\
                            .drop('date_transaction_id', 1)

df 

  Customer first_flag  dollars       date
3      ABC          N     -100 2015-04-04
0      ABC          Y      100 2015-10-11
4      ABC          N     -100 2015-12-12
2      BCD          N     -300 2015-01-01
1      BCD          N      150 2015-03-05
Run Code Online (Sandbox Code Playgroud)

首先first_flag用整数值替换.

df.first_flag = df.first_flag.replace({'N' : 0, 'Y' : 1})
Run Code Online (Sandbox Code Playgroud)

现在,groupbyCustomer检查cumsumWRT的maxfirst_flag.

df = df.groupby('Customer')[['date', 'first_flag', 'dollars']]\
                .apply(lambda x: x[x.first_flag.cumsum() == x.first_flag.max()])\
                .reset_index(level=0)
df
  Customer       date  first_flag  dollars
0      ABC 2015-10-11           1      100
4      ABC 2015-12-12           0     -100
2      BCD 2015-01-01           0     -300
1      BCD 2015-03-05           0      150
Run Code Online (Sandbox Code Playgroud)

可选:用旧Y/ N使用替换积分值

df.first_flag = df.first_flag.replace({0 : 'N', 1 : 'Y'})  
df

  Customer       date first_flag  dollars
0      ABC 2015-10-11          Y      100
4      ABC 2015-12-12          N     -100
2      BCD 2015-01-01          N     -300
1      BCD 2015-03-05          N      150
Run Code Online (Sandbox Code Playgroud)