테이블:Customers
+-------------+---------+
| 열 이름 | 유형 |
+-------------+---------+
| 아이디 | 정수 |
| 이름 | varchar |
+-------------+---------+
id는 이 테이블의 기본 키(고유한 값을 갖는 열)입니다.
이 표의 각 행은 고객의 ID와 이름을 나타냅니다.
테이블:Orders
+-------------+------+
| 열 이름 | 유형 |
+-------------+------+
| 아이디 | 정수 |
| 고객 ID | 정수 |
+-------------+------+
id는 이 테이블의 기본 키(고유한 값을 갖는 열)입니다.
customerId는 Customers 테이블의 ID에 대한 외래 키(참조 열)입니다.
이 표의 각 행은 주문 ID와 주문한 고객의 ID를 나타냅니다.
아무것도 주문하지 않은 모든 고객을 찾는 솔루션을 작성하세요.
결과 표를 원하는 순서 대로 반환합니다 .
결과 형식은 다음 예와 같습니다.
예 1:
입력:
고객 테이블:
+----+-------+
| 아이디 | 이름 |
+----+-------+
| 1 | 조 |
| 2 | 헨리 |
| 3 | 샘 |
| 4 | 최대 |
+----+-------+
주문표:
+----+------------+
| 아이디 | 고객 아이디 |
+----+------------+
| 1 | 3 |
| 2 | 1 |
+----+------------+
산출:
+----------+
| 고객 |
+----------+
| 헨리 |
| 맥스 |
+----------+
내가 한 풀이
import pandas as pd
import numpy as np
def find_customers(customers: pd.DataFrame, orders: pd.DataFrame) -> pd.DataFrame: # 아무것도 주문하지 않은 모든 고객을 찾는 솔루션을 작성하세요.
# 두 df merge
left_df = pd.merge(customers, orders,
left_on='id', # customers DataFrame의 키
right_on='customerId', # orders DataFrame의 키
how='left' # 왼쪽(customers) DataFrame의 모든 데이터를 유지
)
# print('레프트조인 결과', left_df)
no_order_customers = left_df[left_df['customerId'].isna()]
no_order_customers = no_order_customers.rename(columns={'name':'customers'})
return no_order_customers[['customers']] # cusomerId랑 일치하지 않는 이름들 반환
customer_data = {
'id' : [1, 2, 3, 4],
'name' : ['Joe', 'Henry', 'Sam', 'Max']
}
customers = pd.DataFrame(customer_data)
order_data = {
'id' : [1, 2],
'customerId' : [3, 1]
}
orders = pd.DataFrame(order_data)
result = find_customers(customers, orders) # 출력결과는 이름
print(result)
트러블 슈팅
처음에 customer_data, order_data 각각 두개의 테이블 처럼 분리하듯
데이터 프레임 분리하는것도 익숙 하지 않았다.
거기다가 left_on, right_on은 처음 배운 개념..
그외에 레프트 조인, isna 활용(일치 하지 않는 행 조회), column명 변경
다른 공부 하다보니 까먹었다..😅
게다가 SQL 개념을 판다스에다 적용하려니 힘들다..
| 개념 | SQL (데이터베이스) | Pandas (파이썬) |
|---|---|---|
| 데이터 구조 | 테이블 (Table) | 데이터프레임 (DataFrame) |
| 연결(Join) | JOIN | pd.merge() |
| 연결 기준 | ON Table1.Key = Table2.ForeignKey | left_on= , right_on= |
| 필터링 (NULL) | WHERE Column IS NULL | df[df['Column'].isna()] |
머지를 안쓴 풀이 제미나이의 풀이
import pandas as pd
def find_customers_alt(customers: pd.DataFrame, orders: pd.DataFrame) -> pd.DataFrame:
# 1. 주문 테이블에서 'customerId' 열의 고유한 값(즉, 주문한 고객 ID)을 가져옵니다.
# 결과는 pandas Series 또는 NumPy 배열이 됩니다.
ordered_ids = orders['customerId'].unique()
# 2. 고객(customers) DataFrame을 필터링합니다.
# customers['id'].isin(ordered_ids): 'id'가 ordered_ids에 포함되면 True
# ~: (틸드)는 NOT 연산자로, 결과가 True인 것을 False로, False인 것을 True로 반전시킵니다.
# 즉, 주문 ID 리스트에 포함되지 않는 고객만 선택합니다.
no_order_customers = customers[~customers['id'].isin(ordered_ids)]
# 3. 요구 사항에 맞게 'name' 열만 선택하고 컬럼 이름을 'customers'로 변경합니다.
result_df = no_order_customers[['name']]
result_df = result_df.rename(columns={'name': 'customers'})
return result_df
# --- 데이터 ---
customer_data = {
'id' : [1, 2, 3, 4],
'name' : ['Joe', 'Henry', 'Sam', 'Max']
}
customers = pd.DataFrame(customer_data)
order_data = {
'id' : [1, 2],
'customerId' : [3, 1]
}
orders = pd.DataFrame(order_data)
# --- 함수 실행 및 출력 ---
result = find_customers_alt(customers, orders)
print("--- 대체 풀이 최종 결과 ---")
print(result)