Select 不同 df 列中基于条件的列中的值数

Select number of values from column based on condition in a different df column

我正在为一所大学创建一个虚拟数据集来测试云存储和仪表板系统。我目前正在尝试为给定学期的每个学生 ID 分配课程。这将是现实生活中的课程注册步骤。大多数学生满载,4 classes,有些学生用 3,2 或 1 class,概率递减。

我有两个 pandas DataFrame,'courses' 和 'students_master'。

'courses' 有 1100 行,看起来像这样:

  subject_id course_id SECTION_SUBJECT        SECTION_SUBJECT_DESC  \
0        HCH   HCH-101            HPCH  Community Health Promotion   
1        HCH   HCH-102            HPCH  Community Health Promotion   
2        HCH   HCH-103            HPCH  Community Health Promotion   
3        HCH   HCH-104            HPCH  Community Health Promotion   
4        HCH   HCH-105            HPCH  Community Health Promotion 

'students_master' 有 27054 行,看起来像这样:

 ID_year_id  cohort      ids  level num_classes
0       22180  2013FA  1001269      4           4
1       49919  2013FA  1000206      4           4
2       48206  2013FA  1000524      4           2
3       40649  2013FA  1000233      4           3
4       29733  2013FA  1000533      4           2

此时我正在尝试创建一个新列 students_master['selections'],我在其中使用 'num_classes' 列中的数字 1-4 来随机select 课程 ['course_id'] 中的一些 course_ids。生成的列值将是像 [HCH-101, TWI-302,...]

这样的小列表

当我使用这段代码时:

list(courses['course_id'].sample(4))

有效,结果:

['EVS-406', 'BFN-201', 'ATS-105', 'BOL-103']

我曾尝试使用 .apply 以及基本的 for 循环,但没有成功。我认为最有前途的方法是'vectorize'。所以我写了这个 .select 语句:

selections=[]
conditions = [
        (students_master['num_classes']==4),
        (students_master['num_classes']==3),
        (students_master['num_classes']==2),
        (students_master['num_classes']==1)
]
choices = [
        ([list(courses['course_id'].sample(4))]),
        ([list(courses['course_id'].sample(3))]),
        ([list(courses['course_id'].sample(2))]),
        ([list(courses['course_id'].sample(1))])
]


selections.append(np.select(conditions, choices))

它收到错误:“形状不匹配:对象无法广播到单个形状”

非常感谢任何有关如何解决此问题的建议。

这个,你可以使用apply来保证每个学生的课程不重复:

selection = student_master['num_classes'].apply(lambda x: np.random.choice(course['course_id'], x, replace=False) )