파이썬 베이직 (6) - 문제풀이
# 문제 1 - Seaborn 라이브러리에서 제공하는 Diamond 데이터셋을 활용하여 다음을 수행하세요:
1) x, y, z 중 하나라도 0인 데이터를 삭제하세요.
2) x, y, z 를 곱해 'volume' 칼럼을 생성하세요.
3) 범주형 변수인 cut, color, clarity를 머신러닝 모델에 활용할 수 있도록 수치형으로 변환합니다.
- `cut`: `Fair` = 1, `Good` = 2, `Very Good` = 3, `Premium` = 4, `Ideal` = 5로 인코딩하세요.
- `color`: `E`, `I`, `J`, `H`, `F`, `G`, `D`를 각각 1부터 7로 인코딩하세요.
- `clarity`: - `SI2`와 `SI1` → `1` (S 그룹), - `VS1`와 `VS2` → `2` (VS 그룹), - `VVS2`와 `VVS1` → `3` (VVS 그룹), - `I1`과 `IF` → `4` (I 그룹).
diamonds = sns.load_dataset("diamonds")
diamonds['volume'] = diamonds['x']*diamonds['y']*diamonds['z']
diamonds = diamonds.drop(diamonds[diamonds['volume'] == 0].index)
diamonds["cut"] = diamonds["cut"].astype(str)
diamonds["color"] = diamonds["color"].astype(str)
diamonds["clarity"] = diamonds["clarity"].astype(str)
def encode_cut (x):
if x == 'Fair':
return 1
elif x == 'Good':
return 2
elif x == 'Very Good':
return 3
elif x == 'Premiun':
return 4
else:
return 5
diamonds['cut'] = diamonds['cut'].apply(encode_cut)
def encode_color (x):
if x == 'E':
return 1
elif x == 'I':
return 2
elif x == 'J':
return 3
elif x == 'H':
return 4
elif x == 'F':
return 5
elif x == 'G':
return 6
else:
return 7
diamonds['color'] = diamonds['color'].apply(encode_color)
def encode_clarity (x):
if x == 'SI2' and x == 'SI1':
return 1
elif x == 'VS1' and x == 'VS2':
return 2
elif x == 'VVS2' and x == 'VVS1':
return 3
else:
return 4
diamonds['clarity'] = diamonds['clarity'].apply(encode_clarity)
정답
# 코드 1
diamonds = sns.load_dataset("diamonds")
# Categorical -> String 변환
diamonds["cut"] = diamonds["cut"].astype(str)
diamonds["color"] = diamonds["color"].astype(str)
diamonds["clarity"] = diamonds["clarity"].astype(str)
# x * y * z = 0 삭제
diamonds = diamonds[~((diamonds['x']==0) | (diamonds['y']==0) | (diamonds['z']==0))]
# volume column 만들기
diamonds['volume'] = diamonds['x'] * diamonds['y'] * diamonds['z']
⊙ 인코딩 방법 1
# cut 인코딩
diamonds.loc[diamonds["cut"] == "Fair", "cut"] = 1
diamonds.loc[diamonds["cut"] == "Good", "cut"] = 2
diamonds.loc[diamonds["cut"] == "Very Good", "cut"] = 3
diamonds.loc[diamonds["cut"] == "Premium", "cut"] = 4
diamonds.loc[diamonds["cut"] == "Ideal", "cut"] = 5
# color 인코딩
diamonds.loc[diamonds["color"] == "E", "color"] = 1
diamonds.loc[diamonds["color"] == "I", "color"] = 2
diamonds.loc[diamonds["color"] == "J", "color"] = 3
diamonds.loc[diamonds["color"] == "H", "color"] = 4
diamonds.loc[diamonds["color"] == "F", "color"] = 5
diamonds.loc[diamonds["color"] == "G", "color"] = 6
diamonds.loc[diamonds["color"] == "D", "color"] = 7
# clarity 그룹화 및 인코딩
diamonds.loc[diamonds["clarity"].isin(["SI2", "SI1"]), "clarity"] = 1
diamonds.loc[diamonds["clarity"].isin(["VS1", "VS2"]), "clarity"] = 2
diamonds.loc[diamonds["clarity"].isin(["VVS2", "VVS1"]), "clarity"] = 3
diamonds.loc[diamonds["clarity"].isin(["I1", "IF"]), "clarity"] = 4
.loc[조건, "cut"]: 조건에 맞는 행의 cut 컬럼 값을 특정 숫자로 변경
⊙ 인코딩 방법 2
# cut 인코딩
diamonds["cut"] = diamonds["cut"].replace({
"Fair": 1, "Good": 2, "Very Good": 3, "Premium": 4, "Ideal": 5
})
# color 인코딩
diamonds["color"] = diamonds["color"].replace({
"E": 1, "I": 2, "J": 3, "H": 4, "F": 5, "G": 6, "D": 7
})
# clarity 그룹화 및 인코딩
diamonds["clarity"] = diamonds["clarity"].replace({
"SI2": 1, "SI1": 1, # S 그룹
"VS1": 2, "VS2": 2, # VS 그룹
"VVS2": 3, "VVS1": 3, # VVS 그룹
"I1": 4, "IF": 4 # I 그룹
})
⊙ 인코딩 방법 2
# cut 인코딩 : 컷 등급을 정수로 매핑하는 딕셔너리 이용
cut_mapping = {"Fair": 1, "Good": 2, "Very Good": 3, "Premium": 4, "Ideal": 5}
diamonds["cut"] = diamonds["cut"].map(cut_mapping)
# color 인코딩
color_mapping = {"E": 1, "I": 2, "J": 3, "H": 4, "F": 5, "G": 6, "D": 7}
diamonds["color"] = diamonds["color"].map(color_mapping)
# clarity 그룹화 및 인코딩
clarity_mapping = {
"SI2": 1, "SI1": 1, # S 그룹
"VS1": 2, "VS2": 2, # VS 그룹
"VVS2": 3, "VVS1": 3, # VVS 그룹
"I1": 4, "IF": 4 # I 그룹
}
diamonds["clarity"] = diamonds["clarity"].map(clarity_mapping)
참고 : https://blockdmask.tistory.com/531
⊙ 인코딩 방법 3
cut_dictionary = {'Fair' : 1 , 'Good' : 2, 'Very Good' : 3, 'Premium' : 4, 'Ideal' : 5}
color_dictionary = {'E':1,'I':2,'J':3,'H':4,'F':5,'G':6,'D':7}
clarity_dictionary = {'SI2':1,'SI1':1,'VS1':2,'VS2':2,'VVS2':3,'VVS1':3,'I1':4,'IF':4}
diamonds['cut'] = diamonds['cut'].apply(lambda x: cut_dictionary[x])
diamonds['color'] = diamonds['color'].apply(lambda x: color_dictionary[x])
diamonds['clarity'] = diamonds['clarity'].apply(lambda x: clarity_dictionary[x])
주의할 점
replace()와 map()의 차이
- map: 시리즈 객체에서 사용하며, 매핑되지 않은 경우, Nan값 반환
- replace: DataFrame 또는 Series에서 사용 가능하며, 매핑되지 않은 값도 명시적으로 변경하거나 그대로 유지 가능
# 문제 2 - 학생 성적 관리 시스템 - 다음 요구사항에 맞게 3개의 함수를 작성하세요.
1) 학생들의 이름과 성적을 딕셔너리에 저장하고, 출력하는 함수를 작성하세요. (add_student(grades, name, score)
2) 성적 평균을 반환하는 함수를 작성하세요. (calculate_average(grades))
3) 최고 점수 학생을 반환하는 프로그램 작성하세요. (find_top_students(grades))
- 출력결과를 참고하여, 같은 양식으로 출력되도록 함수를 작성하세요.
- 힌트: 딕셔너리 자료형에서 max와 min값 구하는 방법에 대해 필요한 경우, 아래 링크를 참고하세요. https://note.nkmk.me/en/python-dict-value-max-min/
정답
def add_student(grades, name, score):
grades[name] = score
print(f"Added {name} with score {score}.")
def calculate_average(grades):
return sum(grades.values())/len(grades)
def find_top_student(grades):
top_score = max(grades.key=grades.get)
top_student = max(grades)
return top_student, top_score
# Example usage
grades = {}
add_student(grades, "Alice", 85)
add_student(grades, "Bob", 92)
add_student(grades, "Charlie", 78)
print(f"Average score: {calculate_average(grades):.2f}")
top_student, top_score = find_top_student(grades)
print(f"Top student: {top_student} with score {top_score}")