내일배움캠프

[내일배움캠프] TIL 23일차 26.01.23(금)

nom_de_plume 2026. 1. 23. 21:04

파이썬/전처리/시각화 성취도 평가 풀이 

 

Q1. 아래 코드의 출력 결과로 올바른 것은?

a = [1,2,3]
b = a
b.append(4)
print(a)
print(b)

답) B. [1,2,3,4] / [1,2,3,4]

=> 얕은 복사

 

Q2. 아래 코드의 출력 결과로 올바른 것은?

d = {"a":1,"b":2}
print(d.get("c"))
print(d.get("c",0))

답) A. None / 0

=> 키값 지정안해주면 None 출력, 키값 지정하면 키값 출력

 

Q3. 아래 코드가 입력 10,20에서 실패하는 가장 적절한 이유는?

a, b = map(int, input().split())

답) B. split()은 기본이 공백 분리라 10,20이 2개로 안 나뉘고, 콤마가 남아 int()변환도 실패한다

 

Q4. 아래 코드의 출력 결과로 올바른 것은?
nums = [3,1,2]
result = nums.sort()
print(nums)
print(result)

답) C. [1, 2, 3] / None

=> .sort()는 반환값이 없어서 result의 출력값은 None이고 원본이 정렬된다.

=> 'nums.sorted(nums)'하면 result의 출력값이 정렬되고 원본은 유지된다.

 

Q5. 아래 코드의 출력 결과로 올바른 것은?

a = [1,2,3]
a.append([4,5])

b = [1,2,3]
b.extend([4,5])

print(a)
print(b)

답) B. [1, 2, 3, [4, 5]] / [1, 2, 3, 4, 5]

=> .append() 에 리스트 들어있으면 리스트 속에 그대로 리스트 추가

=> .extend() 에 리스트 들어있어도 모두 펴서 원래 리스트에 추가

 

Q6. 더 큰 수 반환 함수

def bigger(a,b):
    if a>=b:
        return a
    else:
        return b

=> 두 수가 같다면 어떤 수가 나와도 된다고 문제에 명시되었기 때문에 '>=' 과 '>' 상관x 

 

Q7. return 오류 디버깅

=> return이 없기 때문에 return의 기본값 None이 출력된다.

함수 선언부 함수 이름 함수 매1. 아래 코드의 출력 결과로 올바른 것은?

a = [1,2,3]
b = a
b.append(4)

print(a)
print(b)

답) B. [1,2,3,4] / [1,2,3,4]

 

=> 얕은 복사

 

 

 

Q2. 아래 코드의 출력 결과로 올바른 것은?

d = {"a":1,"b":2}

print(d.get("c"))
print(d.get("c",0))

답) A. None / 0

 

=> 키값 지정안해주면 None 출력, 키값 지정하면 키값 출력

 

 

 

Q3. 아래 코드가 입력 10,20에서 실패하는 가장 적절한 이유는?

a, b = map(int, input().split())

답) B. split()은 기본이 공백 분리라 10,20이 2개로 안 나뉘고, 콤마가 남아 int()변환도 실패한다

 

 

 

Q4. 아래 코드의 출력 결과로 올바른 것은?

nums = [3,1,2]
result = nums.sort()

print(nums)
print(result)

답) C. [1, 2, 3] / None

 

=> .sort()는 반환값이 없어서 result의 출력값은 None이고 원본이 정렬된다.

=> 'nums.sorted(nums)'하면 result의 출력값이 정렬되고 원본은 유지된다.

 

 

Q5. 아래 코드의 출력 결과로 올바른 것은?

a = [1,2,3]
a.append([4,5])

b = [1,2,3]
b.extend([4,5])

print(a)
print(b)

답) B. [1, 2, 3, [4, 5]] / [1, 2, 3, 4, 5]

 

=> .append() 에 리스트 들어있으면 리스트 속에 그대로 리스트 추가

=> .extend() 에 리스트 들어있어도 모두 펴서 원래 리스트에 추가

 

 

 

Q6. 더 큰 수 반환 함수

def bigger(a,b):
    if a>=b:
        return a
    else:
        return b

=> 두 수가 같다면 어떤 수가 나와도 된다고 문제에 명시되었기 때문에 '>=' 과 '>' 상관x 

 

 

 

Q7. return 오류 디버깅

def double(n):
    n * 2

result = double(5)
print(result)

=> return이 없기 때문에 return의 기본값 None이 출력된다.

 

함수 선언부 함수 이름 (함수 매개변수):

             함수구현

함수반환 = 함수호출

 

Q8. 0 입력 시 종료하는 누적합 프로그램

total = 0 

while True:
    num = int(input())
    if num == 0:
        break
    total += num

print(total)

=> 보통 입력값이 0일 때 종료하는 반복문은 "무한 루프"를 만든 뒤 내부에서 break로 빠져나오는 방식을 사용한다. result 대신 파이썬의 예약어인 True를 사용해야 한다. while문에는 조건문이나 True/False가 입력되어야한다.

 

## 미니게임

def cc(n): 
    cnt= 0 
    while n!=0:
        n= int(input())
        cnt += n
    return cnt
n= int(input())
result = cc(n)
print(result)

=> 3을 입력하면 n에 3이 들어가 0이 아니기 때문에 while문에서 재입력을 받아 3이 사라지고 cnt에 입력된다. 그 후 다시 0이 아니기 때문에 while문이 반복되어 재입력받고 마지막으로 입력받은 값만 cnt에 추가되어 출력된다.

수정 답안)

def cc(n): 
    cnt = n 
    while n!=0:
        n= int(input())
        cnt += n
    return cnt
n= int(input())
result = cc(n)
print(result)

 

 

Q9. Class 출력 예측 + 수정

class Student:
    scores = []

    def add_score(self, score):
        self.scores.append(score)

s1 = Student()
s2 = Student()

s1.add_score(90)
s2.add_score(80)

print(s1.scores)
print(s2.scores)

=> scores가 클래스 변수라서 s1, s2 인스턴스가 같은 리스트를 공유한다.

=> 그리고 리스트는 가변 객체(mutable)라서 append가 공유 객체에 반영된다.

수정 답안)

class Student:
    
    def __init__(self):
        self.scores = []

    def add_score(self, score):
        self.scores.append(score)

s1 = Student() 
s2 = Student()

s1.add_score(90)
s2.add_score(80)

print(s1.scores)
print(s2.scores)

 

 

Q10. 아래 코드 실행 후 order_date컬럼 dtype으로 가장 적절한 것은?

orders = pd.read_csv("bootcamp_orders.csv", parse_dates=["order_date"])
orders["order_date"].dtype

답) B. datetime64[ns] (M8[ns])

=> 날짜 데이터이기 때문

 

Q11. DataFrame df에서 첫 번째 행의 age 값을 가져오는 코드로 가장 적절한 것은?

답) A. df.loc[0, "age"]

=> loc는 라벨 기반이다. 행라벨, 열라벨을 그대로 적으라는 것이다.

=> 첫번째 행이 행라벨 0을 의미, age값이 열라벨 "age" 의미

=> iloc는 위치기반이다. 행위치, 열위치를 적어야한다.

 

Q12. 아래 코드의 동작으로 올바른 설명은?

orders2 = orders.drop_duplicates(subset=["order_id"], keep="first")

답) B. 중복 행을 제거하되, order_id별로 첫 번째 행만 남긴다

=> keep="first" : 처음만 남기기

=> keep="last" : 마지막만 남기기

=> keep=false : 다 지우기

 

Q13. 아래 코드 결과로 올바른 것은?

import numpy as np
import pandas as pd

df = pd.DataFrame({
    "category": ["coffee", "coffee", "tea"],
    "rating": [5, np.nan, 3]
})

print(df.groupby("category")["rating"].count())

답) B. coffee=1, tea=1

=> np.nan값은 세지 않는다. 그렇기에 1 / 1 씩만 count가 된다.

=> sum()하면 5 / 3이 된다. (np.nan 무시)

 

Q14. 아래 설명 중 가장 올바른 것은?

merged = orders.merge(customers, on="customer_id", how="left")

답) C. orders의 모든 행은 유지되고, 매칭되지 않는 고객 정보는 NaN이 된다

=> merge하면 메인과 서브를 찾고 기준점, 방식으로 판단

=> 메인은 무너지지 않는다.

 

Q15. 원본 주문행(df_orders)에서 카테고리별 총매출 합계 막대그래프를 가장 확실하게 그리는 방법은?

답) C. df_sum = df_orders.groupby("category")["revenue"].sum().reset_index()로 합계를 만든 뒤, sns.barplot(data=df_sum, x="category", y="revenue")

=> (~별, ~ 묶어서, ~로 합쳐서) 는 모두 카테고리별 groupby를 시사한다.

 

Q16. 그래프에서 라벨/눈금이 겹칠 때 가장 흔히 쓰는 해결 방법은?

답) A. plt.tight_layout()

=> B,C,D는 모두 pandas 문법

 

Q17. 데이터 로드 & 기본 점검
1. customers/orders를 pandas로 읽고 각각 shape 출력

import pandas as pd

customers = pd.read_csv("bootcamp_customers.csv")
orders = pd.resd_csv("bootcamp_orders.csv")

print(customers.shape)
print(orders.shpae)

2. orders에서 order_id 기준 중복 행 개수 출력

orders.duplicated(subset=["order_id"]).sum()

3. customers와 orders 각각에 대해 컬럼별 결측치 개수를 출력

customers.isna().sum()
orders.isna().sum()

 

Q18. 주문 데이터 정리 + 매출 컬럼 만들기

orders 데이터에 대해 아래를 수행하세요.

 

1. order_id 기준 중복 제거(첫 행 유지)

import pandas as pd

customers = pd.read_csv("bootcamp_customers.csv")
orders = pd.resd_csv("bootcamp_orders.csv")

orders_clean = orders.drop_duplication(subset=['order_id'], keep="first").copy()

2. discount_rate 결측치는 0으로 채우기

orders_clean['discount_rate'] = orders_clean['discount_rate'].fillna(0)

3. revenue = unit_price * quantity * (1 - discount_rate) 컬럼 생성

orders_clean['revenue'] = orders_clean["unit_price"] * orders_clean["quantity"] * (1 - orders_clean["discount_rate"])

4. 정리된 orders의 행 개수와 revenue 총합을 출력

orders_clean['revenue'].sum()

len(orders_clean) # orders_clean.shape

 

Q19. 고객 정보 붙이고 도시별 매출 요약 만들기

import pandas as pd

customers = pd.read_csv("bootcamp_customers.csv")
orders = pd.resd_csv("bootcamp_orders.csv")

orders_clean = orders.drop_duplication(subset=['order_id'], keep="first").copy()
orders_clean['discount_rate'] = orders_clean['discount_rate'].fillna(0)
orders_clean['revenue'] = orders_clean["unit_price"] * orders_clean["quantity"] * (1 - orders_clean["discount_rate"])

1. Q18의 정리된 orders를 customers와 left merge 하세요.

merged = orders_clean.merge(customers, on="customer_id", how="left")

2. city가 결측치인 경우 "UNKNOWN"으로 채우세요.

merged['city'] = merged['city'].fillna("UNKNOWN")

3. 도시별로 아래 집계를 구하세요.

  • order_cnt : 도시별 고유 주문 수 (nunique(order_id))
  • customer_cnt : 도시별 고유 고객 수 (nunique(customer_id))
  • revenue_sum : 도시별 매출 합계
  • 정렬: revenue_sum 내림차순, city 오름차순
summary = (
    merged.groupby("city")
    .agg(
        order_cnt=("order_id", "nunique"),
        customer_cnt=("customer_id","nunique"),
        revenue_sum=("revenue", "sum"),
    )
    .sort_values(["revenue_sum","city"], ascending=[False, True])
)

 

Q20. 시각화 리포트(2개 그래프)

Q18~Q19 결과를 활용해 아래 2개 그래프를 그리세요.

 

1. 카테고리별 총매출 막대그래프(Bar Plot)

  • x: category, y: revenue_sum(총합)
  • 제목/축 라벨 포함
  • (권장) 매출 내림차순으로 카테고리 정렬
import pandas as pd

customers = pd.read_csv("bootcamp_customers.csv")
orders = pd.resd_csv("bootcamp_orders.csv")

orders_clean = orders.drop_duplication(subset=['order_id'], keep="first").copy()
orders_clean['discount_rate'] = orders_clean['discount_rate'].fillna(0)
orders_clean['revenue'] = orders_clean["unit_price"] * orders_clean["quantity"] * (1 - orders_clean["discount_rate"])

# 카테고리별 총매출 막대그래프(Bar Plot)
category_sum = (
    orders_clean.groupby("category")["revenue"].sum()
    .reset_index(name="revenue_sum")
    .sort_values("revenue", ascending=False)
)

import matplotlib.pyplot as plt
import seaborn as sns

sns.barplot(data=category_sum, x="category", y="revenue_sum")


### 부가적

plt.figure(figsize=(7,4))
sns.barplot(data=category_sum, x="category", y="revenue_sum")
plt.title("Total Revenue by Category")
plt.xlabel("Category")
plt.ylabel("Revenue Sum")
plt.tight_layout()
plt.show()

 

2. 일자별 매출 추이 선그래프(Line Plot)

  • x: order_date, y: daily_revenue
  • 제목/축 라벨 포함
  • 날짜 라벨이 겹치면 회전 처리
# 일자별 매출 추이 선그래프(Line Plot)
daily_revenue = (
    orders_clean.groupby("order_date")['revenue'].sum()
    .reset_index(name="daily_revenue")
    .sort_values("order_date")
)

plt.plot(daily_revenue['order_date'], daily_revenue['daily_revenue'], marker="o")

 

## 부가적

plt.figure(figsize=(7,4))
plt.plot(daily_revenue['order_date'], daily_revenue['daily_revenue'], marker="o")
plt.title("Daily Revenue Trend")
plt.xlabel("Order Date")
plt.ylabel("Daily Revenue")
plt.tight_layout()
plt.show()