根据另一个数据框中的日期条件创建新列

时间:2019-09-11 14:38:48

标签: pandas numpy

我有两个数据框-一个包含交易/订单信息,另一个包含发送广告系列电子邮件时的数据。

import pandas as pd
email_data = {'Email' : ['test@gmail.com', 'test@gmail.com', 'test2@gmail.com', 'test2@gmail.com'],
                     'email_sent_date' : ['2019-08-05', '2019-08-01', '2019-09-09', '2019-09-05'],
                     'CampaignName' : ['Campaign1', 'Campaign2', 'Campaign2', 'Campaign1']}

email_df = pd.DataFrame(email_data)

transaction_data = {'Email' : ['test@gmail.com', 'test@gmail.com', 'test2@gmail.com', 'test2@gmail.com'],
         'order_date' : ['2019-09-05', '2019-09-10', '2019-09-05', '2019-09-10']}

transaction_df = pd.DataFrame(transaction_data)

我正在尝试回答问题-对于给定的交易,在该交易之前最近发送的电子邮件是什么?

我有一个使用pd.apply的解决方案,但是它不是特别快,而且对于较大的交易量来说可能不可持续。我想知道是否有更好的方法可以做到这一点。

email_df.sort_values(by='email_sent_date', inplace=True)

def find_recent_email(x,df):
    #df should be the email_df, sorted by customer_email and date, in ascending order
    #so the most recent email is last
    return df[df['Email'] == x]['email_sent_date'].tail(1).values[0]

transaction_df['recent_email_date'] = pd.to_datetime(transaction_df['Email'].apply(find_recent_email, args=(email_df,)))

1 个答案:

答案 0 :(得分:1)

首先将列转换为日期时间(如果已经是日期时间,则忽略此步骤):

svn info $url

在两个数据框中对日期进行排序:

Out-Null

使用merge_asof,我们可以首先使用email_df.email_sent_date=pd.to_datetime(email_df.email_sent_date) transaction_df.order_date=pd.to_datetime(transaction_df.order_date) 参数在a=email_df.sort_values('email_sent_date').drop('CampaignName',1) b=transaction_df.sort_values('order_date') 上进行合并,然后使用Email执行asof合并:

by=

direction='nearest'

使用的参数:

  

by:列名或列名列表   在执行合并操作之前,请在这些列上进行匹配。

     

left_by:列名   在左侧DataFrame中要匹配的字段名称。

     

right_by:列名   在正确的DataFrame中要匹配的字段名称。

     

direction:“向后”(默认),“向前”或“最近”   是搜索之前,之后还是最接近的匹配项。

您还可以查看pd.merge_asof(a,b,by='Email',left_on='email_sent_date', right_on='order_date',direction='nearest') 参数,其内容为:

  

tolerance:整数或Timedelta,可选,默认无   在此范围内选择最大公差;必须与合并索引兼容。