[Today I Learn]
- SQL codekata
- Python codekata
- 데이터 전처리 / 시각화 세션
[SQL codekata]
- 문제 1.
1. 문제 링크: https://leetcode.com/problems/classes-with-at-least-5-students/
2. 정답 코드
select class
from Courses
group by class
having count(distinct student) >= 5
3. 개선할 점: (student, class) is the primary key for this table 조건이 있으므로 굳이 distinct 사용 안해도 됨. 필요 없는데 굳이 사용할 경우 쿼리 내에서 중복 제거 확인을 하고 임시 메모리 사용을 한다는 점에서 비효율적임 → distinct 제거
select class
from Courses
group by class
having count(*) >= 5
- 문제 2.
1. 문제 링크: https://leetcode.com/problems/find-followers-count/submissions/1889384296/
2. 정답 코드
select user_id, count(*) as followers_count
from Followers
group by user_id
order by user_id asc
- 문제 3.
1. 문제 링크: https://leetcode.com/problems/biggest-single-number/description/
2. 정답 코드
select max(mn.num) as num
from MyNumbers mn
where exists (
select 1
from MyNumbers m
where m.num = mn.num
group by m.num
having count(*) = 1
)
select max(mn.num) as num
from MyNumbers mn
where mn.num in (
select m.num
from MyNumbers m
group by m.num
having count(*) = 1
)
- MAX() 함수를 사용하면, 만약 조건에 맞는 데이터가 하나도 없을 경우(즉, 서브쿼리 결과가 빈 값일 경우)
- 집계 함수인 MAX()는 자동으로 NULL을 반환
3. 개선할 점: 두 쿼리 모두 정답을 도출하지만, 사실 이 문제는 서브쿼리를 FROM 절에 사용하면 훨씬 간단하고 빠르게 해결할 수 있음
select max(subquery.num) as num
from (select m.num
from MyNumbers m
group by m.num
having count(*) = 1
) as subquery
[Python codekata]
- 문제 1.
1. 문제 링크: https://school.programmers.co.kr/learn/courses/30/lessons/120803?language=python3
2. 정답 코드
def solution(num1, num2):
if num1>50000 or num1<-50000 or num2>50000 or num2<-50000:
raise ValueError("-50000~50000 사이의 값만 입력할 수 있습니다")
answer = num1 - num2
return answer
solution = lambda num1, num2: num1 - num2
- 문제 2.
1. 문제 링크: https://school.programmers.co.kr/learn/courses/30/lessons/120807
2. 정답 코드
def solution(num1, num2):
if num1 == num2:
return 1
else:
return -1
3. 개선할 점: 한 줄로 삼항 연산자 사용하면 더 간단하게 작성할 수 있음
def solution(num1, num2):
return 1 if num1 == num2 else -1
def solution(num1, num2):
return (num1 == num2) * 2 - 1
- boolean 값을 이용해서 return 1과 -1을 if 문 사용하지 않고 작성
- 문제 3.
1. 문제 링크: https://school.programmers.co.kr/learn/courses/30/lessons/120820
2. 정답 코드
def solution(age):
answer = 2022 - age + 1
return answer
3. 개선할 점: 2022년이라는 특정 연도가 바뀔 때를 대비하여 변수화 하기
def solution(age):
current_year = 2022
answer = current_year - age + 1
return answer
- 문제 4.
1. 문제 링크: https://school.programmers.co.kr/learn/courses/30/lessons/120806
2. 정답 코드
def solution(num1, num2):
answer = num1/num2*1000
return int(answer)
3. 개선할 점:
- 문제점
- 단순히 int(num1 / num2 * 1000)으로 작성할 경우, 부동 소수점(Floating Point) 연산이 개입됨
- 컴퓨터는 실수를 2진수로 표현하며, 이 과정에서 무한 소수는 근사치로 저장되기에 **정밀도 손실(Rounding Error)**이 발생함
- 해결 방안
- 연산 순서의 중요성: 나눗셈(/)을 먼저 수행하면 즉시 실수형(float)으로 형 변환이 일어남
- 반면, 곱셈(*)을 먼저 수행하여 분자를 키운 뒤 정수 나눗셈(//)을 수행하면, 모든 연산이 정수 도메인(Integer Domain) 내에서 완결됨
- 성능적 이점: CPU의 FPU(실수 연산 장치)를 사용하는 것보다 ALU(정수 연산 장치)를 사용하는 것이 일반적으로 사이클 소모가 적으며, int() 캐스팅 오버헤드도 줄일 수 있음
- 연산 순서의 중요성: 나눗셈(/)을 먼저 수행하면 즉시 실수형(float)으로 형 변환이 일어남
def solution(num1, num2):
answer = num1*1000//num2
return answer
5. 또다른 정답 코드
def solution(num1, num2):
import math
answer = math.trunc(1000*num1/num2)
return answer
- math 라이브러리를 불러와서 math.trunc 함수 사용해서 소숫점 자리 제거
- but, 함수 호출할 때마다 import 하는건 비효율적이므로 import문은 함수 밖으로 빼기
import math
def solution(num1, num2):
answer = math.trunc(1000*num1/num2)
return answer
[ 데이터 전처리 / 시각화 2-1 , 2-2 ]
- 인덱싱 핵심: .loc vs .iloc
- 열 선택 : 필요한 컬럼만 남기기
- 조건 필터링 (불리언 인덱싱) : "결제 완료 + A매장 + 오전"
- 정렬 : "메뉴별 판매수량 TOP"을 뽑을 준비
- 클리닝 기본기 4종 세트
- 결측치 처리 : dropna vs fillna
- 중복 처리: duplicated / drop_duplicates
- 미니 결과물 만들기: "매출 컬럼 추가 + 회의용 테이블 정리"
- 저장: 2회차 결과물을 파일로 남기기 (3회차를 위해 필수)
- 행/열 선택 패턴
- 추천하는 실무 습관 2가지
- 조건 필터링 (불리언 인덱싱)
- 정렬(sort_values, sort_index)이 필요한 이유
- 클리닝(정제)의 4대 문제
https://myun0506.tistory.com/67
결측, 중복 전처리: Pandas Cleaning 정제
[ 데이터 전처리 / 시각화 2-1 , 2-2 ]- 인덱싱 핵심: .loc vs .iloc .loc : 라벨(이름) 기반 (행/열 이름으로 접근) ; label(이름표)행/열의 '이름표'를 기준으로 선택ex) 인덱스가 0,1,2가 아니라 A001,A002 같은
myun0506.tistory.com
[ 아티클 스터디 ]
https://yozm.wishket.com/magazine/detail/1816/
그 데이터는 잘못 해석되었습니다 | 요즘IT
무엇이든 데이터가 있으면 쉽게 결정을 내릴 수 있을 것 같습니다. 하지만 현업에서는 데이터가 있어도 결정을 내리기 어려운 상황들이 있습니다. 특히 데이터를 통한 의사결정을 내릴 때, 가장
yozm.wishket.com
- 주요 포인트:
- 생존자 편향의 오류
- 전체 대상을 기준으로 잡는 것이 중요
- 심슨의 역설
- 전체 지표와 그룹을 나눈 지표의 방향성이 다르게 나타나는 상황
- 사용자를 나눌 수 있는 기준은 다양하기 때문에, 지나치게 작게 나누는 것은 복잡도를 높여 해석하기 어려워짐
- 특성이 다를 수 있다고 생각하는 성별, 연령대, 기기 타입, 신규/기존 여부 등의 기준들을 미리 정하여, 그 기준으로 지표를 살펴보는 것이 효과적임
- 상관관계를 통한 성급한 일반화
- 사람은 연관성을 찾고 연결하는 것에 강점이 있어, 비슷해 보이는 패턴이 있다면 쉽게 일반화하는 경향이 있어서 지표 간의 관계를 파악하여 해석하려는 유혹에 쉽게 빠지게 됨
- 상관성은 있으나 인과성이 없는 경우는 제 3의 공통 원인이 존재할 가능성이 높음
- 상관관계를 통한 성급한 일반화의 함정에 빠지지 않기 위해, 사용자의 행동과 심리를 인지적으로 구조화하고 두 지표에 동시에 영향을 줄 공통 원인이 있는지 살펴봐야함
- 또한, 새로운 구조로 지표 간의 관계를 파악하는 과정이 꼭 필요함
- 목적에 맞지 않는 지표 선택
- 정확히 어떤 관점에서 개선할지 목적을 명확히 해야함
- ex) CTA 버튼 조회 유저수 대비 CTA 버튼 클릭 유저수라는 지표 대신 CTA 버튼 조회수 대비 CTA 버튼 클릭수로 지표 변경
- 세이건 표준 참고하기!!
- “특별한 주장에는 특별한 근거가 필요하다 (Extraordinary Claims Require Extraordinary Evidence, ECREE)” - 칼 세이건의 ‘세이건 표준’
- 생존자 편향의 오류
실제로 내가 데이터 분석 하는 과정에서 너무나 발생하기 쉬운 오류들이라 찔렸음...
내가 보고자 하는 문제상황이 있을 때 지표를 알맞게 설정하는게 얼마나 중요한 일인지 다시 깨닫게 됨
특히 정해진 문제상황이 있으면 전체상황을 보는 것보다 그 핵심 상황을 보기 위해서 일부 대상을 분석하려고 할 수 있는데
그렇게 되면 실제 상황과 다른 왜곡된 상황으로 이해를 할 수 있다는 걸 깨달으니 굉장히 무섭기도 하고 경각심을 일깨우는 계기가 되었음
또한 상관관계를 통한 성급한 일반화 부분에선 그냥 내 얘기를 하는 것 같았음
어떤 프로젝트에서 무언가를 분석하는 과정에 있으면 더 이를 명확하고, 강력하게 분석을 해야한다는 강박관념에
실제 인과성이 없는 두 이벤트를 인과성이 있다고 성급하게 분석할 수 있고 실제로 내 경험에서도 그런 적이 있었던 것 같음
그래서 더욱이 이 두가지 이벤트와 모두 연결되는 제 3의 공통 원인이 있는지 더 고려해보는 것이 얼마나 중요할지 깨닫게 됨
'[데이터분석] 부트캠프 TIL' 카테고리의 다른 글
| 20260122 TIL (0) | 2026.01.22 |
|---|---|
| 20260120 TIL (0) | 2026.01.20 |
| 20260116 TIL (0) | 2026.01.16 |
| 20260115 TIL (1) | 2026.01.15 |
| 20260114 TIL (1) | 2026.01.14 |