2025.02.24 - [프로그래밍/Python 관련 정보] - [Pandas] Table of Contents
사실 저는 Cross join이 그렇게 필요한가? 라는 생각을 했었는데요... cross join은 다음 예와 같이 모든 카테고리의 조합을 계산(테이블에 정보가 없어서 Null 혹은 0을 넣는 한이 있어도)해야하는 경우에 사용합니다.
제가 처음에 작성했던 솔루션은 아래와 같았습니다.
def students_and_examinations(students: pd.DataFrame, subjects: pd.DataFrame, examinations: pd.DataFrame) -> pd.DataFrame:
tmp = examinations.groupby(['student_id', 'subject_name'], as_index=False).agg(attended_exams=('subject_name', 'count'))
return subjects.merge(tmp, how='left', on='subject_name').merge(students, how='left', on='student_id')[['student_id', 'student_name', 'subject_name', 'attended_exams']].sort_values(by=['student_id', 'subject_name'])
그런데 이렇게 코드를 실행해보면
와 같은 결과물이 나타납니다. 제 머릿속에서는 어차피 subjects 테이블을 기준으로 놓고 'left join'시킨거니까 subjects 테이블에 있는 항목인 Math, Physics, Programming 이것들은 문제에서 원하는 형태로 결과 테이블에도 나타날 것이라고 착각한 것이죠. 물론 tmp에 physics항목이 하나도 없었다면 subjects 테이블의 physics가 1줄 나타나고 Null로 채워졌을 겁니다. 그렇지만 지금은 physics라는 (subject join key) 가 student_id 칼럼값 기준으로 : 1, (2, 3... 건너뛰고), 13 ... 에 존재하기 때문에, 이 존재하는 칼럼들을 가져옵니다.
즉, 제가 생각한대로 다중 join key 현상이 발생하긴 하지만 그 '다중'이 문제에서 원하는 것처럼 모든 조합에 대해서 발생한 것이 아니라 examinations 테이블에 각각의 id 별로 다른 개수의 '다중'이 발생하고 그 각각의 개수에 맞춰 다중행이 생성되는 것입니다. tmp 테이블을 정렬시켜서 아래와 같이 놓고 보면 좀 더 이해하기가 쉬웠던 것 같습니다.
우리가 흔히 교집합, 합집합 등의 개념으로 inner join, outer join을 비유하는데요.. 아무리 합집합이라도 합치기 전 원래 갖고있는 엔트리보다 확장이 되는 것은 아니다는 점에 주목해보면 어떤 착각을 했는지 확인할 수 있습니다.
그래서 제대로 쿼리를 짜려면 Cross Join을 수행해주어야 합니다. Leetcode 순위 랭크 정답은 아래와 같네요
def students_and_examinations(students: pd.DataFrame, subjects: pd.DataFrame, examinations: pd.DataFrame) -> pd.DataFrame:
df = students.merge(subjects, how='cross')
examinations.rename(columns={'subject_name':'subject_name2'},inplace=True)
df_result=df.merge(examinations, how='left', left_on=['student_id','subject_name'], right_on=['student_id','subject_name2'])
return df_result.groupby(['student_id','student_name','subject_name'], dropna=False)['subject_name2'].count().reset_index(name='attended_exams')
'프로그래밍 > Python 관련 정보' 카테고리의 다른 글
[Python 기초] append vs. extend (0) | 2025.05.18 |
---|---|
[Pandas] 사용자 정의 정렬하기 (0) | 2025.05.16 |
[Pandas 기초] Series의 칼럼명 변경 (0) | 2025.04.28 |
[Pandas 기초] DataFrame 집계 method (0) | 2025.04.27 |
[Pandas문제풀이 - groupby + apply의 활용] Group Sold Products By The Date (0) | 2025.04.27 |