嵌套查询/在Pandas

时间:2016-11-12 21:29:07

标签: python pandas

我正在使用Pandas(第一次)来确定人员在课程出勤时是否满足先决条件。下面的代码返回了所需的结果,但我确信有更好的方法可以实现相同的结果。

确定您是否可以进行物理学的标准如下;

(Math_A OR Math_B OR Math_C) AND (Eng_A OR Eng_B) AND NOT (Physics)

我的问题是可以采用哪种效率或替代方法来实现这项任务。

阅读嵌套查询等,我无法想出一种方法来比较一个查询中的多个查询。理想情况下,我希望有一个声明可以检查这个人是否满足先决条件,但到目前为止,我已经失败了。

数据集 - 通常包含> 20,000条记录

Emplid,Name,CourseId,CourseName
123,David,P12,Mathematics A
123,David,P13,Mathematics B
123,David,P14,Mathematics C
123,David,P32,Engineering A
456,Sally,P33,Engineering B
789,Roger,P99,Physics

代码

修改以简化可读性 - Thx Boud。

import pandas as pd

def physics_meets_prereqs():

    df = pd.DataFrame({'Emplid':['123','123', '123', '123', '456', '789'],
                   'Name':['David','David','David','David','Sally','Roger'],
                   'CourseId':['P12','P13','P14','P32','P33','P99'],
                   'CourseName':['Mathematics A','Mathematics B','Mathematics C','Engineering A','Engineering B', 'Physics']
                    })

    # Get datasets of individually completed courses
    has_math = df.query('CourseId == "P12" or CourseId == "P13" or CourseId == "P14"')
    has_eng = df.query('CourseId == "P32" or CourseId == "P33"')
    has_physics = df.query('CourseId == "P99"')

    # Get personnel who have completed math and engineering
    has_math_and_eng = has_math[(has_math['Emplid'].isin(has_eng['Emplid']))]

    # Remove personnel who have completed physics
    has_math_and_eng_no_physics = has_math_and_eng[~(has_math_and_eng['Emplid'].isin(has_physics['Emplid']))]

    print(has_math_and_eng_no_physics)

physics_meets_prereqs()

输出

  CourseId     CourseName Emplid   Name
0      P12  Mathematics A    123  David
1      P13  Mathematics B    123  David
2      P14  Mathematics C    123  David

输出导致David被识别为满足物理课程的先决条件。它列出了他3次,我还没想出如何限制。我实现这一目标的方式肯定可以改进。

简而言之

向我展示已完成至少一门数学课程,至少一门工程课程并尚未完成物理课程的人员名单。

2 个答案:

答案 0 :(得分:4)

pivoted = df.groupby(['Name', df.CourseName.str.split().str[0]]) \
            .CourseId.size().gt(0).unstack(fill_value=False)

pivoted

enter image description here

matches = pivoted.query('Engineering & Mathematics & ~Physics')
matches

enter image description here

df.query('Name in @matches.index')

enter image description here

答案 1 :(得分:1)

使用query键入更自然的数学关系:

df.query('CourseId == "P12" or CourseId != "P99"')