如何在 Python 中使用 Pandas 查找精度 @ N

How to find precision @ N using Pandas in Python

我想计算A级系统的比例,但只包括一定数量级的问题。我从以下数据开始

system     question    grade
Sys1       Is?         A
Sys1       Is?         A
Sys1       Is?         C
Sys1       How?        B
Sys1       How?        A
Sys1       How?        F
Sys1       How?        F
Sys2       Is?         A
Sys2       Is?         A
Sys2       Is?         B
Sys2       How?        A

Precision = A等级的比例

N = 问题在系统中至少有 N 个等级

我想计算每个系统的精度@n。例如,Precision @ 2 将是每个系统对于至少具有 2 个等级

的问题的 'A' 等级的比例

我正在努力将计算结合起来,因为我刚刚在学习 Pandas。下面是我试图使用 N=2:

实现的示例
  1. 按系统分组,提问并过滤掉大小 < 2 的组

    大小 = df.groupby('system', 'question').size()
    尺寸[尺寸 >= 2]
    系统问题
    sys1 是? 3个
            如何? 4个
    sys2是? 3个

  1. 获取每个系统每个年级的大小(计数)

    df.groupby(['system', 'question', 'grade']).size()
    系统题等级
    sys1 是? A2
                          1个
              如何?一个 1
                          乙 1
                          女2
    sys2是? A2
                          乙 1
             如何?一个 1
    
  2. 加入小组,只保留步骤 1 中未过滤掉的问题

    ???

  3. 总结每个系统的所有 A,然后除以系统中的总成绩

    ???

想要的结果:

system   precision
Sys1         0.43
Sys2         0.66

Sys1 的精度为 0.42,因为它在 7 个等级中有 3 个 A。 "Sys2 How?" 不包括在内,因为它的成绩少于 2 个 (N=1),因此 Sys2 在 "Is?"

的 3 个成绩中有 2 个 A

非常感谢您的帮助。

生成布尔掩码:

mask = df.groupby(['system', 'question']).size().ge(2)
mask

system  question
Sys1    How?         True
        Is?          True
Sys2    How?        False
        Is?          True
dtype: bool

执行 groupby + size + unstack 并用 0 填充 NaNs

A = df.groupby(['system', 'question', 'grade']).size().unstack(fill_value=0)
A

基于掩码的子集:

B = A[mask]
B

groupby w.r.t 第一个索引轴和计算总和:

C = B.groupby(level=0).sum()

取列 A 并除以 DF's 跨列总和:

C['A']/C.sum(1)

system
Sys1    0.428571
Sys2    0.666667
dtype: float64

要输出 DF 而不是小数舍入到 2 位:

pd.DataFrame(C['A']/C.sum(1), columns=['precision']).round(2)

尝试这样的事情:

df = pd.DataFrame({'system':['Sys1', 'Sys1', 'Sys1', 'Sys1', 'Sys1', 'Sys1', 'Sys1', 'Sys2', 'Sys2', 'Sys2', 'Sys2'],
               'question': ['Is?', 'Is?', 'Is?', 'How?', 'How?', 'How?', 'How?', 'Is?', 'Is?', 'Is?', 'How?'],
               'grade': ['A', 'A', 'C', 'B', 'A', 'F', 'F', 'A', 'A', 'B', 'A']})

q_size_df = pd.DataFrame(df.groupby(['system', 'question']).size(), columns=['q_size']).reset_index()

df2 = df.merge(q_size_df)

df2[df2['q_size']>=2].groupby(['system']).apply(lambda x: len(x[x['grade']=='A']) / len(x))

输出为:

system
Sys1    0.428571
Sys2    0.666667
dtype: float64

其背后的想法是首先计算有问题的尺寸指标,然后将该指标合并回原始 df,最后在过滤后的 df 上计算统计数据。这样做的好处是将来可以添加更多过滤列(即条件),而无需在过滤列本身之外实现额外的逻辑。