[코딩테스트]/[Pandas]

[LeetCode - Pandas] (Easy) 1280. Students and Examinations

잰잰' 2025. 4. 18. 17:44
Table: Students

+---------------+---------+
| Column Name   | Type    |
+---------------+---------+
| student_id    | int     |
| student_name  | varchar |
+---------------+---------+

student_id는 이 테이블의 기본 키(고유 값이 있는 열)입니다.
이 테이블의 각 행은 학교에서 한 학생의 ID와 이름을 포함하고 있습니다.

Table: Subjects

+--------------+---------+
| Column Name  | Type    |
+--------------+---------+
| subject_name | varchar |
+--------------+---------+

subject_name은 이 테이블의 기본 키(고유 값이 있는 열)입니다.
이 테이블의 각 행은 학교에서 하나의 과목 이름을 포함하고 있습니다.

Table: Examinations

+--------------+---------+
| Column Name  | Type    |
+--------------+---------+
| student_id   | int     |
| subject_name | varchar |
+--------------+---------+

이 테이블에는 기본 키(고유 값이 있는 열)가 없습니다. 중복된 값이 있을 수 있습니다.
학생 테이블(Students)의 각 학생은 과목 테이블(Subjects)의 모든 과목을 수강합니다.
이 테이블의 각 행은 student_id가 subject_name 과목의 시험에 참석했음을 나타냅니다.

 

문제

각 학생이 각 시험에 참석한 횟수를 찾는 솔루션을 작성하세요.

결과 테이블은 student_id와 subject_name 순으로 정렬되어야 합니다.

결과 형식은 다음 예와 같습니다.

Example 1:

Input: 
Students table:
+------------+--------------+
| student_id | student_name |
+------------+--------------+
| 1          | Alice        |
| 2          | Bob          |
| 13         | John         |
| 6          | Alex         |
+------------+--------------+
Subjects table:
+--------------+
| subject_name |
+--------------+
| Math         |
| Physics      |
| Programming  |
+--------------+
Examinations table:
+------------+--------------+
| student_id | subject_name |
+------------+--------------+
| 1          | Math         |
| 1          | Physics      |
| 1          | Programming  |
| 2          | Programming  |
| 1          | Physics      |
| 1          | Math         |
| 13         | Math         |
| 13         | Programming  |
| 13         | Physics      |
| 2          | Math         |
| 1          | Math         |
+------------+--------------+
Output: 
+------------+--------------+--------------+----------------+
| student_id | student_name | subject_name | attended_exams |
+------------+--------------+--------------+----------------+
| 1          | Alice        | Math         | 3              |
| 1          | Alice        | Physics      | 2              |
| 1          | Alice        | Programming  | 1              |
| 2          | Bob          | Math         | 1              |
| 2          | Bob          | Physics      | 0              |
| 2          | Bob          | Programming  | 1              |
| 6          | Alex         | Math         | 0              |
| 6          | Alex         | Physics      | 0              |
| 6          | Alex         | Programming  | 0              |
| 13         | John         | Math         | 1              |
| 13         | John         | Physics      | 1              |
| 13         | John         | Programming  | 1              |
+------------+--------------+--------------+----------------+

설명 :
결과 테이블에는 모든 학생과 모든 과목이 포함되어야 합니다.

- Alice는 수학 시험을 3번, 물리학 시험을 2번, 프로그래밍 시험을 1번 참석했습니다.

- Bob은 수학 시험을 1번, 프로그래밍 시험을 1번 참석했고, 물리학 시험에는 참석하지 않았습니다.

- Alex는 어떤 시험에도 참석하지 않았습니다.

- John은 수학 시험을 1번, 물리학 시험을 1번, 프로그래밍 시험을 1번 참석했습니다.

 

✏️ 풀이

import pandas as pd

def students_and_examinations(students: pd.DataFrame, subjects: pd.DataFrame, examinations: pd.DataFrame) -> pd.DataFrame:
    df = examinations.groupby(['student_id', 'subject_name'])['subject_name'].count().reset_index(name='attended_exams')

    result = students.merge(subjects, how='cross')
    result = result.merge(df, how='left', on=['student_id', 'subject_name']).fillna(0)

    return result.sort_values(by=['student_id', 'subject_name'])

1. groupby를 통해 각 학생별 과목별 시험 참석 횟수를 구한다

2. 시험에 참석하지 않은 학생들은 0으로 나와야 하므로 students와 subjects를 cross join한다

3. 2번에 1번의 데이터를 merge 한다

4. 데이터가 없는 학생은 fillna(0)으로 0을 넣어준다

5. 정렬은 student_id, subject_name으로 한다