使用 Pandas 计算分组计数时的案例

Posted

技术标签:

【中文标题】使用 Pandas 计算分组计数时的案例【英文标题】:Calculate a case when count in a group by using Pandas 【发布时间】:2021-08-01 15:06:15 【问题描述】:

我是使用 python 的初学者, 我正在尝试仅在一个代码行中计算打开率比率(两个不同计数之间的比率)。 我的数据框是这样的:

   df = pd.DataFrame([
    (142, 1, 'open' , 'Mobile'),
    (144, 2, 'open' , 'Mobile'),
    (144, 1, 'delivered', 'Web'),
    (142, 1, 'delivered', 'Mobile'),
    (142, 2, 'delivered', 'Web'),
    (144, 1, 'open', 'Web'),
    (142, 2, 'open', 'Mobile')
], columns=['sent_mail_id', 'customer_id', 'event' , 'Tool_used'])

我想计算打开率,同时按列 Tool_used 使用 Pandas 进行分组。 在 SQL 语言中是这样的:

  select 
  Tool_used ,  
  count(distinct case when event='open' then sent_mail_id end)/count(distinct case when 
  event='delivered' then sent_mail_id end)
  from df
  group by 1

请注意,我需要明确计算 sent_mail_id,因为需要唯一计数。 谢谢

【问题讨论】:

您能添加一些预期的输出布局吗?是否会是每组的“开放率比率”列? send_email_id 将如何显示? 【参考方案1】:

使用crosstab,因此只需将列opendeliveredSeries.reset_index 分开:

df1 = pd.crosstab(df['Tool_used'], df['event'])
print (df1)
event      delivered  open
Tool_used                 
Mobile             1     3
Web                2     1

df2 = df1['open'].div(df1['delivered']).reset_index(name='open rate ratio')
print (df2)
  Tool_used  open rate ratio
0    Mobile              3.0
1       Web              0.5

如果需要groupby比较和聚合sum,但我认为这更复杂:

a = (df['event'] == 'open').groupby(df['Tool_used']).sum()
b = (df['event'] == 'delivered').groupby(df['Tool_used']).sum()

df2 = a.div(b).reset_index(name='open rate ratio')
print (df2)
  Tool_used  open rate ratio
0    Mobile              3.0
1       Web              0.5

使用自定义函数的解决方案(大数据时性能更差):

def f(x):
    return (x == 'open').sum() / (x == 'delivered').sum()

df2 = df.groupby('Tool_used')['event'].agg(f).reset_index(name='open rate ratio')
print (df2)
  Tool_used  open rate ratio
0    Mobile              3.0
1       Web              0.5

【讨论】:

谢谢@jezrael,有没有使用udf并将其应用于groupby的解决方案? @pellerossapelles - 你认为 pyspark 吗?不幸的是不知道:( 不,我的意思是创建一个函数(带有 def 语句的函数)并在 groupby 上使用 .apply() 。对不起,我的语言真的不是技术性的 @pellerossapelles - 可能,但性能问题。 @pellerossapelles - 添加到答案中。【参考方案2】:

看看这是否是你需要的,在每个组中都有一列open rate ratio

df1 = ((df.loc[df['event'] == 'open'].groupby('Tool_used')['event'].count() 
       / 
       df.loc[df['event'] == 'delivered'].groupby('Tool_used')['event'].count())
       .to_frame(name='open rate ratio')
      ).reset_index()

结果:

print(df1)



  Tool_used  open rate ratio
0    Mobile              3.0
1       Web              0.5

【讨论】:

以上是关于使用 Pandas 计算分组计数时的案例的主要内容,如果未能解决你的问题,请参考以下文章

pandas 条件分组和计数值

在 pandas / python 中对条件值进行分组和计数

每月、每年分组的值计数 - Pandas

在 Pandas 中分组和计数

pandas使用groupby函数基于指定分组变量对dataframe数据进行分组使用agg函数计算每个分组不同数值变量的聚合统计值agg参数为字典指定不同变量的聚合计算统计量的形式

Pandas 数据框分组和计数与 Python 中的验证