Pandas数据框中并发调用分数的区别

3
我正在尝试使用用户@Garret提供的修改后的代码分析以下数据集中的几个内容,但是我遇到了一些问题。
数据集有一列显示客户是由现场代理还是自动机器进行操作。 我正在尝试获取同步呼叫之间的差异,其中成员首先连接到代理,然后没有连接。通话必须具有相同的呼叫原因,并且在时间戳方面必须放置在初始呼叫之后。此外,在之间可以有其他原因的呼叫。
这是数据集:
data = [['bob13', 1, 'returns','automated',' 2019-08-18 10:12:00'],['bob13', 0, 'returns','automated',' 2019-03-18 10:12:00'],\
        ['bob13', 8, 'returns','agent',' 2019-04-18 10:15:00'],['rach2', 2, 'shipping','automated',' 2019-04-19 10:15:00'],\
        ['bob13', 0, 'returns','agent',' 2019-05-18 11:12:00'],['rach2', 0, 'shipping','agent',' 2019-04-18 11:15:00'],\
        ['bob13', 3, 'returns','agent',' 2019-02-18 10:12:00'],['rach2', 8, 'shipping','agent',' 2019-05-19 10:15:00'],\
       ['rach2', 7, 'shipping','automated',' 2019-06-19 10:15:00'],['roy', 4, 'exchange','agent','2019-03-26 17:36:00'],\
       ['roy', 5, 'exchange','automated','2019-01-28 09:48:00']]

df = pd.DataFrame(data, columns = ['member_id', 'survey_score','call_reason','connection','time_stamp']) 
df.sort_values(by=['time_stamp']).head(20)

member_id   survey_score    call_reason connection  time_stamp
6   bob13        3            returns   agent       2019-02-18 10:12:00
1   bob13        0            returns   automated   2019-03-18 10:12:00
2   bob13        8            returns   agent       2019-04-18 10:15:00
5   rach2        0            shipping  agent       2019-04-18 11:15:00
3   rach2        2            shipping  automated   2019-04-19 10:15:00
4   bob13        0            returns   agent       2019-05-18 11:12:00
7   rach2        8            shipping  agent       2019-05-19 10:15:00
8   rach2        7            shipping  automated   2019-06-19 10:15:00
0   bob13        1            returns   automated   2019-08-18 10:12:00
10  roy          5            exchange  automated   2019-01-28 09:48:00
9   roy          4            exchange  agent       2019-03-26 17:36:00





我期望得到的输出如下:
member_id    call_reason    automated    agent    score differential
bob13         returns           0          3            -3
bob13         returns           1          0             1
rach2         shipping          2          0             2
rach2         shipping          7          8            -1


基本上,我们只是想了解在呼叫原因和连接方面两个调用之间的差异。第一个调用是当成员连接到代理时,第二个调用必须在第一个调用之后,基于时间戳,必须是同样的原因,并且必须连接到自动化系统。如果在其间有为其他原因放置的通话,则没有问题。我尝试的代码如下:

grp = df.query('connection=="automated"').\
    groupby(['member_id', 'call_reason'])
df['OutId'] = grp.time_stamp.transform(lambda x: x.rank())
df.head(10)
grp = df.groupby(['member_id', 'call_reason'])
df['Id'] = grp.OutId.transform(lambda x: x.bfill())
df.head(10)
agent = df.query('connection=="agent"').\
    groupby(['member_id', 'call_reason', 'Id']).survey_score.last()

automated = df.query('connection=="automated"').\
    groupby(['member_id', 'call_reason', 'Id']).survey_score.last()

ddf = pd.concat([automated, agent], axis=1,
                keys=['automated', 'agent'])
ddf['score_differential'] = ddf.automated - ddf.agent


我得到的输出是:
ddf.dropna().head(10)

                              automated     agent   score_differential
member_id   call_reason Id          
rach2         shipping  2.0      7           8.0          -1.0
roy           exchange  1.0      5           4.0           1.0



再次运行,预期输出应为:

member_id    call_reason    automated    agent    score differential
bob13         returns           0          3            -3
bob13         returns           1          0             1
rach2         shipping          2          0             2
rach2         shipping          7          8            -1


注意:我希望解决方案能够灵活,这样我就可以分析一些不同的情况,例如:
  1. 仅自动化呼叫之间的差异
  2. 仅与代理人连接的呼叫之间的差异
  3. 当初始呼叫连接到代理时以及在第二个呼叫中无论连接类型如何之间的差异
如果您能提供额外的帮助,将不胜感激!

我不确定我理解了。为什么bob13只有1个自动化和3个代理。根据您的示例,应该是23吗?而且我不明白score_diff到底是什么,因为我看不到第3行(bob13 8)适合输出。 - Quang Hoang
抱歉,我应该让它更清楚。预期输出中的自动化和代理列是来自通话中成员连接代理或自动化机器的调查分数。因此,bob13 的输出行返回 0 3 -3 是与数据集中以下两个通话相关的:6 bob13 3 returns agent 2019-02-18 10:12:001 bob13 0 returns automated 2019-03-18 10:12:00 - GlupiDebil
但是预期输出中的第二个bob13显示“自动化为1,代理为0”,为什么它使用的是第4行和第0行而不是第2行和第0行? - Matt W.
@MattW。我这样做是因为bob13有两个同时连接到代理的条目,在第2和第4行。所以我跳过了第2行中的条目,以获取第4行上最新的条目,然后再获取与第0行的自动连接条目之间的差异。不过,说实话,如果它获取2和0之间的差异,对我来说也不是什么大问题。顺便感谢您的帮助。 - GlupiDebil
明白了,我刚刚发布了一个答案。如果有效,请告诉我。 - Matt W.
1个回答

2
你可以通过创建一个函数,然后将该函数应用于groupby中的组来实现此操作。
设置初始数据框:
import pandas as pd

data = [['bob13', 1, 'returns','automated',' 2019-08-18 10:12:00'],['bob13', 0, 'returns','automated',' 2019-03-18 10:12:00'],\
        ['bob13', 8, 'returns','agent',' 2019-04-18 10:15:00'],['rach2', 2, 'shipping','automated',' 2019-04-19 10:15:00'],\
        ['bob13', 0, 'returns','agent',' 2019-05-18 11:12:00'],['rach2', 0, 'shipping','agent',' 2019-04-18 11:15:00'],\
        ['bob13', 3, 'returns','agent',' 2019-02-18 10:12:00'],['rach2', 8, 'shipping','agent',' 2019-05-19 10:15:00'],\
       ['rach2', 7, 'shipping','automated',' 2019-06-19 10:15:00'],['roy', 4, 'exchange','agent','2019-03-26 17:36:00'],\
       ['roy', 5, 'exchange','automated','2019-01-28 09:48:00']]

df = pd.DataFrame(data, columns = ['member_id', 'survey_score','call_reason','connection','time_stamp']) 
df.sort_values(by=['time_stamp']).head(20)
df['time_stamp'] = pd.to_datetime(df['time_stamp'])

df
   member_id  survey_score call_reason connection          time_stamp
0      bob13             1     returns  automated 2019-08-18 10:12:00
1      bob13             0     returns  automated 2019-03-18 10:12:00
2      bob13             8     returns      agent 2019-04-18 10:15:00
3      rach2             2    shipping  automated 2019-04-19 10:15:00
4      bob13             0     returns      agent 2019-05-18 11:12:00
5      rach2             0    shipping      agent 2019-04-18 11:15:00
6      bob13             3     returns      agent 2019-02-18 10:12:00
7      rach2             8    shipping      agent 2019-05-19 10:15:00
8      rach2             7    shipping  automated 2019-06-19 10:15:00
9        roy             4    exchange      agent 2019-03-26 17:36:00
10       roy             5    exchange  automated 2019-01-28 09:48:00

每当我尝试解决这样的问题时,我会将一个特定的组分离出来。所以我只隔离了bob13,并尝试复制达到我们想要的结果的步骤,然后将其放入函数中:
我们按时间对数据框进行排序,然后创建名为next_connection和'next_score'的新列。这些将下一个结果的结果转移,以便我们在该行内拥有它。我们删除任何缺失值(因为该组的最后一个没有下一个),我们隔离任何连接为agent且下一个连接为automated的行。我们重命名列以匹配您的输出,并计算得分差异。
def function_(df):
    df = df.sort_values('time_stamp')
    df['next_connection'] = df.connection.shift(-1)
    df['next_score'] = df.survey_score.shift(-1)
    df = df.dropna()
    df = df[(df.connection == 'agent') & (df.next_connection == 'automated')]
    df = df.rename(columns={'survey_score':'agent', 'next_score':'automated'})
    df['score differential'] = df['automated'] - df['agent']
    return df

现在我们将其应用到按member_idcall_reason分组的数据框中。最初的回答。
g = df.groupby(['member_id', 'call_reason']).apply(function_)

g[['member_id','call_reason','automated','agent','score differential']].reset_index(drop=True)

  member_id call_reason  automated  agent  score differential
0     bob13     returns        0.0      3                -3.0
1     bob13     returns        1.0      0                 1.0
2     rach2    shipping        2.0      0                 2.0
3     rach2    shipping        7.0      8                -1.0

1
非常感谢这个非常有帮助的描述和这里惊人的社区!对于像我这样经营着一家小型(不太赚钱)企业并且必须尝试自己进行分析以节省成本的人来说,这非常有帮助。再次感谢。 - GlupiDebil
没问题,如果你需要任何帮助,请告诉我。 - Matt W.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接