- FACTS : 코드카타와 이전에 못 푼 개인과제 5,6번을 도전해봤다. 개인과제 5번은 다른 부분은 수월하게 풀렸지만 마지막에 이상치 계산하는 부분에서 numpy 배열의 개념을 확실히 몰라서 한참 시간이 걸렸다.
- FEELINGS : 오늘 푼 코드카타와 개인 과제 문제에서는 2차원 데이터들을 다루는 함수들을 많이 접했다. 1차원도 머리 아픈데 2차원이라니..! 그래도 현실에는 엑셀만 봐도 2D데이터가 많으니 제대로 공부해두면 다양하게 활용할 수 있을 것 같은 내용이었다. 어려워질수록 쉬워지는(?) 신기한 파이썬...
행렬에 대한 코드를 짤 때는 머리가 안돌아가서 한참 동안 종이에 적어가며 어떤 값을 기준으로 잡고 for문을 돌려야 하는지 생각했다. 그럴 때는 그냥 단순하게 적어보는게 이해가 빨리 되는것 같다. for문을 쓰지 않고 써보니 공통점이 보여서 어떻게 사용해야할지 감이 왔다.
꼭 아날로그적으로 해봐야 아는 나란 감자... 언제쯤 머리 속으로 쇽쇽 그릴 수 있게 될까?
- FINDINGS : join()의 활용 방법, numpy 특징과 활용 방법
코드카타
#에러 코드
def solution(s):
answer = True
if len(s) in (4,6) and s == int():
return answer
else:
answer = False
return answer
"1234"일 때도 False로 반환됨.
# 정답 코드
def solution(s):
answer = True
if len(s) in (4,6) and s.isdigit():
return answer
else:
return False
isdigit() : 입력값이 숫자로만 구성되어있는지 확인
for문을 사용하기 전에 행렬을 어떻게 반복해야할지 머릿속에 안그려져서 for문을 사용하지 않고 짜봤다.
# 과정
def solution(arr1, arr2):
answer = [arr1[0][0] + arr2[0][0]],[arr1[0][1] + arr2[0][1]],[arr1[1][0] + arr2[1][0]],[arr1[1][1] + arr2[1][1]]
return answer
solution([[1,2],[2,3]] , [[3,4],[5,6]])
#결과 값
([4], [6], [7], [9])
이로써 arr1과 arr2의 각 요소의 길이(j)만큼 덧셈을 반복 -> [arr1[0][0] + arr2[0][0]],[arr1[0][1] + arr2[0][1]]
한 후에, arr1과 arr2의 수(i)만큼 반복 -> [arr1[1][0] + arr2[1][0]],[arr1[1][1] + arr2[1][1]]
def solution(arr1, arr2):
answer = []
for i in range(len(arr1)): #배열의 행 수만큼: [1,2],[2,3]이니까 2번
row = []
for j in range(len(arr1[i])): #각 행의 열 수만큼 반복: [1,2]니까 2번
row.append(arr1[i][j] + arr2[i][j]) #1. arr1[0][0] + arr2[0][0] / 2. arr1[0][1] + arr2[0][1]
answer.append(row) # 1. row = [4] / 2. row =[4,6] -> j반복문 탈출
return answer
solution([[1,2],[2,3]] , [[3,4],[5,6]])
지난번 문제에서도 봤던 join을 사용한 사람도 있었다.
join을 사용하면 튜플 형태로 반환되기에 어떻게 사용해야할지 모르겠어서 안썼는데 사용하니 훨씬 간단하게 해결되어서 활용해 봐야겠다.
#다른 풀이
def solution(arr1, arr2):
answer = [[c + d for c, d in zip(a,b)] for a, b in zip(arr1, arr2)]
return answer
1. zip(arr1, arr2)
- zip() 함수는 arr1과 arr2의 동일한 인덱스에 있는 요소들을 튜플로 묶는다.
- zip([[1, 2], [2, 3]], [[3, 4], [5, 6]]) -> ([1, 2], [3, 4]), ([2, 3], [5, 6])
2. for a, b in zip(arr1, arr2)
- 각 zip에서 반환된 튜플을 a와 b로 unpacking한다.
- 첫 번째 반복:
- a = [1, 2], b = [3, 4]
- 두 번째 반복:
- a = [2, 3], b = [5, 6]
3. [c + d for c, d in zip(a, b)]
- 각 행에 대해 또 다시 zip()을 사용하여 a와 b의 요소들을 묶고
- zip(a,b) ->
- 첫 번째 반복 : zip([1, 2], [3, 4]) -> [(1, 3), (2, 4)]
- 두 번째 반복 : zip([2, 3], [5, 6]) -> [(2, 5), (3, 6)]
- 그 요소들을 각각 c와 d로 unpacking합니다.
- 각 c와 d를 더하여 새로운 리스트를 만든다. : [1+3, 2+4], [2+5, 3+6]
2차원 배열....복잡허다잉....
파이썬 개인과제
문제5. 이상치 탐지하기
- 출제의도
- 외부 모듈을 도입하고 새로운 자료형에 대해서 스스로 학습할 수 있다.
- 새로운 메소드를 이용하여 백분율을 표기할 수 있다.
- 함수의 return 기능을 사용한다.
- 배경
- 데이터에서 이상치를 탐지하는 것은 중요한 문제입니다. 다양한 방법이 있지만 데이터 백분율을 기준으로 이상치를 탐지하는 IQR 기반 방법이 있습니다. IQR은 Inter Quantitle Range의 약자로 다음과 같이 정의 됩니다.
IQR = Q3 - Q1
- 단 Q3는 백분율 상위 25%, Q1는 하위 25%
위 지표를 가지고 상한 이상치와 하한 이상치 기준을 설정하여 사용합니다.
upper limit = Q3 + 1.5*IQR
lowerlimit = Q1 - 1.5*IQR
각 분위수(Q1,Q2,Q3) 는 numpy라고 하는 외부 모듈을 이용해서 손쉽게 구할 수 있습니다.
- 데이터설명
- 주어진 데이터는 학생들의 키 20개입니다.
- [157, 160, 153, 100, 186, 159, 169, 181, 179, 189, 300, 207, 157, 153, 166, 186, 189, 169, 180, 164]
- 요구사항
- 데이터가 주어졌을 때, Q1,Q2,Q3와 상한 이상치, 하한 이상치 기준 그리고 이상치를 식별하는 함수calculate_iqr 를 만들어주세요
- Q1, Q2, Q3을 계산하여 q1, q2, q3 변수에 담아주세요.
- 상한, 하한 이상치를 계산하여 lower_bound, upper_bound에 담아주세요.
- 이상치를 식별하여 outlier 리스트에 담아주세요
- 위 모든 자료형을 반환해주세요.
- 데이터가 주어졌을 때, Q1,Q2,Q3와 상한 이상치, 하한 이상치 기준 그리고 이상치를 식별하는 함수calculate_iqr 를 만들어주세요
- Skeleton 코드
heights = [157, 160, 153, 100, 186, 159, 169, 181, 179, 189, 300, 207, 157, 153, 166, 186, 189, 169, 180, 164]
def calculate_iqr(data):
'''여기에 코드를 작성해주세요'''
import numpy as np
heights = np.array([157, 160, 153, 100, 186, 159, 169, 181, 179, 189, 300, 207, 157, 153, 166, 186, 189, 169, 180, 164])
def calculate_iqr(data):
q1 = np.percentile(data, 25)
q2 = np.percentile(data, 50)
q3 = np.percentile(data, 75)
iqr = q3 - q1
lower_bound = q1 - 1.5*iqr
upper_bound = q3 + 1.5*iqr
outlier = data[(data < lower_bound) | (data > upper_bound)]
answer = (q1, q2, q3, lower_bound, upper_bound, outlier)
return answer
NumPy 배열과 파이썬 리스트의 차이
1) 파이썬 보다 연산이 빠르다.
파이썬 리스트에는 다양한 자료형이 들어가지만 넘파이에는 한가지 자료형만 들어가기 때문.
C언어의 배열처럼 연속적인 메모리 배치를 가지기 때문에 모든 원소가 같은 자료형이어야 해요.
대신 접근과 반복문의 실행이 파이썬리스트보다 훨씬 속도가 빨라요.
2) 복잡한 연산을 쉽게 할 수 있다.
리스트에서는 [ 1, 2 ] * 2 -> [ 1, 2, 1, 2 ]
넘파이에서는 [ 1, 2 ] * 2 -> [ 2, 4 ]
단순히 값을 추가하고 제거하는데는 리스트를 사용하기 좋지만 복잡한 연산이나 배열이 많아질수록 넘파이를 쓰는게 쉽다.
[문제 5번에 대입]
- Numpy를 이용하기 위해서는 Height값을 np.array()로 넘파이 배열로 만들어 준다.
- NumPy에서의 조건문 : 기본적으로 배열의 요소에 대해 조건을 평가할 수 있지만, 배열 자체를 조건문에 직접 사용할 수는 없습니다(If문 사용 불가). NumPy 배열은 여러 요소(1D, 2D, 3D...)를 가지고 있기 때문에, 배열이 참인지 거짓인지 판단하는 것은 모호하기 때문.
-> 따라서 1. Element-wise 조건 평가 로 판단.
outlier = data[(data < lower_bound) | (data > upper_bound)]
# data가 lower_bound보다 작거나(or) data가 upper_bound보다 큰 경우 true를 반환함
# 출력 값 : [False, False, False, True, False,False,...]
# 이 불리언 배열을 사용하여 data 배열에서 이상치인 100과 3을 선택
Numpy 에서의 조건문
1. Element-wise 조건 평가
import numpy as np
data = np.array([1, 2, 3, 4, 5])
# 배열의 각 요소가 3보다 큰지 검사
result = data > 3 # 결과: [False, False, False, True, True]
2. np.where() 함수 사용
result = np.where(data > 3, "크다", "작다")
# 결과: ['작다' '작다' '작다' '크다' '크다']
3. np.any()와 np.all() 사용
# 모든 요소가 3보다 큰지 확인
all_greater = np.all(data > 3) # 결과: False
# 하나라도 3보다 큰지 확인
any_greater = np.any(data > 3) # 결과: True
4. 기본적인 조건문
if np.any(data > 3):
print("3보다 큰 값이 있습니다.")
'내일배움캠프 > TIL' 카테고리의 다른 글
[TIL]250110_코드카타, 파이썬 개인과제 6번 (0) | 2025.01.10 |
---|---|
[TIL]250109_코드카타, 파이썬 베이직반 2회차, 통계학 3회차 (0) | 2025.01.09 |
[TIL]250107_QCC 2회차 문제풀이, 코드카타 (0) | 2025.01.07 |
[TIL]250103기초프로젝트_발표 및 회고 (1) | 2025.01.03 |
[TIL]250102기초프로젝트_코드정리 및 발표자료 완성 (0) | 2025.01.02 |