对电子邮件的平均响应时间

2024-04-28 20:13:24 发布

您现在位置:Python中文网/ 问答频道 /正文

我在一个数据库中有一系列的电子邮件,它们被分成线程,所以下面的数据框将代表一个单独的对话。我试着计算我和被试的平均反应时间。你知道吗

目前,我是通过一个循环,这似乎是非常低效的。是否有任何我不使用的可用功能?我能不能找到一种方法来筛选出唯一的响应?这样我就可以改变时间,然后用这种方法计算差异。你知道吗

示例数据帧。如下图所示,在回复之前,一方可能会发送多封电子邮件。只有第一个应该用来计算响应时间差

Sender    DateTime
Me        ISO8601
Me        ISO8601
Customer  ISO8601
Me        ISO8601
Customer  ISO8601
Customer  ISO8601
Me        ISO8601
Me        ISO8601
Me        ISO8601
Customer  ISO8601

当前操作的伪代码(太长,无法放入完整的实际代码)

# Track who responded last
last_comment_type = None
# Track response numbers (number of times each party responded)
customer_response_count = 0
my_response_count = 0


# Determine who the first sender is (doesn't always have to be me)
if df.ix[df.index.values.min()]['ResponseType'] == customer:
    last_comment_type = 'Customer'
    next_response = df.iloc[1:][df['ResponseType'] = 'Me']
    my_total_response_time += next_response - row
    my_response_count += 1
else:
    last_comment_type = 'Me'
    next_response = df.iloc[1:][df['ResponseType'] = 'Customer']
    customer_total_response_time += next_response - row
    customer_response_count += 1

# Loop over rest of rows and figure out who responded to who.
for row in df.itertuples():
    if row.ResponseType == 'Customer' and last_comment_type == 'Me':
        next_response = df[df.index > row.Index][df['ResponseType'] != 'Customer']
        my_total_response_time += next_response - row 
        my_response_count += 1
    if row.ResponseType == 'Me' and last_comment_type == 'Customer':        
        next_response = df[df.index > row.Index][df['ResponseType'] != 'Me']
        customer_total_response_time += next_response - row     
        customer_response_count += 1    

my_response_avg = my_total_response_time/my_response_count
customer_response_avg = customer_total_response_time/customer_response_count

Tags: dftimeresponsemycountcommentcustomernext
1条回答
网友
1楼 · 发布于 2024-04-28 20:13:24

如果我理解正确,熊猫可以做得更简单。如果您只想计算第一条消息之间的差异:

df['block'] = ((df.Sender != df.Sender.shift()).cumsum())
mean_response_time = df.drop_duplicates('block', keep='first')['DateTime'].diff().mean()

如果要通过Sender计算平均响应时间,可以使用groupby()

df['response_time'] = df.drop_duplicates('block', keep='first')['DateTime'].diff()
gr = df.groupby('Sender').response_time
mean_response_times = gr.sum() / gr.count()

注意:我使用sum/count而不是mean,因为this issuegroupbymean()在将来可能会被修补。


我们把它分解一下。首先,我们需要一个带有可用时间的示例数据帧(这是我建议您在这样的问题中提供的):

times = pd.date_range('10/18/2018', periods=8, freq='H')
df = pd.DataFrame({'Sender': ['A','B','A','A','B','B','B','A'], 'DateTime': times})

这将为您提供如下数据帧:

             DateTime Sender
0 2018-10-18 00:00:00      A
1 2018-10-18 01:00:00      B
2 2018-10-18 02:00:00      A
3 2018-10-18 03:00:00      A
4 2018-10-18 04:00:00      B
5 2018-10-18 05:00:00      B
6 2018-10-18 06:00:00      B
7 2018-10-18 07:00:00      A

df['block'] = ((df.Sender != df.Sender.shift()).cumsum())创建一个新列,其中来自相同Sender的连续行具有相同的编号:

             DateTime Sender  block
0 2018-10-18 00:00:00      A      1
1 2018-10-18 01:00:00      B      2
2 2018-10-18 02:00:00      A      3
3 2018-10-18 03:00:00      A      3
4 2018-10-18 04:00:00      B      4
5 2018-10-18 05:00:00      B      4
6 2018-10-18 06:00:00      B      4
7 2018-10-18 07:00:00      A      5

由于我们所关心的(在版本1中)是从一个Sender发送的第一条消息到下一个发送方发送的第一条消息之间的时间,因此我们可以删除除第一个block具有重复值的行以外的所有行:

df.drop_duplicates('block', keep='first')['DateTime']

它给出了每个特定于Sender的块中每个第一条消息的时间:

0   2018-10-18 00:00:00
1   2018-10-18 01:00:00
2   2018-10-18 02:00:00
4   2018-10-18 04:00:00
7   2018-10-18 07:00:00

如果我们想要所有发送者之间的平均时间,我们需要做的就是添加diff()mean()以获得行之间的平均时间:

df.drop_duplicates('block', keep='first')['DateTime'].diff().mean()

它给出:

Timedelta('0 days 01:45:00')

如果我们想通过发送者获得平均时间,您需要额外的步骤。我们为响应时间创建一个新的列,然后按发送者分组,然后计算平均值。你知道吗

df['response_time'] = df.drop_duplicates('block', keep='first')['DateTime'].diff()
gr = df.groupby('Sender').response_time
mean_response_time = gr.sum() / gr.count()

结果是:

Sender
A   02:00:00
B   01:30:00

注意:如果要计算一个发件人的最后一封邮件与下一个发件人的第一封邮件之间的差值:

df['block'] = ((df.Sender != df.Sender.shift()).cumsum())
df['last_message'] = df.drop_duplicates('block', keep='last')['DateTime']
df['first_message'] = df.drop_duplicates('block', keep='first')['DateTime'].shift(-1)
mean_response_time = (df['first_message'].shift(-1) - df['last_message']).mean()

相关问题 更多 >