Today's Goals
1. SQL 꾸준한 연습 - SQL 코드카타, QCC
2. 파이썬 익숙해지기 - 파이썬 코드카타, pandas 라이브 세션
QCC와 라이브 세션 연속의 날.. 쉽지않다
그래도 QCC 문제를 풀면서 생각 정리의 속도가 빨라진 것 같아서 좋았다.
물론,, 데이터 설명을 제대로 못봐서 외래키 하나 제대로 파악 못하고 몇십분을 끙끙댄건 비밀
역시 뭐든간에 기본 자료를 꼼꼼하게 보는건 중요한 것...
1. SQL 연습
SQL 코드카타
[윈도우 함수가 만능열쇠가 아니다, 조건을 잘 보자]
- 전체 player 중에 첫날 접속하고 다음날도 접속한 player의 비율 구하기 문제
- 무작정 lag 윈도우 함수를 써먹어야겠군 생각
# 오답 쿼리 1
with date_lag as (
select player_id,
event_date,
lag(event_date) over (partition by player_id order by event_date) as pre_event_date
from Activity
)
select round(sum(datediff(event_date, pre_event_date)=1) / count(distinct player_id), 2) as fraction
from date_lag
- 이 쿼리의 문제는, 첫 접속날과 그 다음날 뿐만 아니라, 1일 차이나는 모든 접속 기록을 count하게 됨
- 첫 접속날이라는 조건을 넣지 않은 것이 문제
# 오답 쿼리 2
with date_lag as (
select player_id,
event_date,
lag(event_date) over (partition by player_id order by event_date) as pre_event_date
from Activity
)
select ROUND(sum(datediff(event_date, pre_event_date)=1) / (SELECT COUNT(DISTINCT player_id) FROM Activity), 2) as fraction
from date_lag
where (player_id, pre_event_date) in (SELECT player_id, MIN(event_date) AS first_event_date
FROM Activity
GROUP BY player_id)
- 이 쿼리는 모든 player가 첫 접속만 있고 다음날 접속하지 않았을 때, 값 자체가 null이 되어버려서 문제
# 정답 쿼리
with first_event_date as (
select player_id,
min(event_date) as first_event_date
from Activity
group by player_id
)
select round(sum(datediff(a.event_date, b.first_event_date)=1) / count(distinct a.player_id), 2) as fraction
from Activity a join first_event_date b on a.player_id=b.player_id
- 이렇게 윈도우 함수 없이 min으로 첫 접속날만 구하고 두 테이블을 합치면 해결할 수 있는 문제였음
- 윈도우 함수를 만능이라고 여기지 말고 다양한 방법을 고민하자
[where vs having, 처리 속도에 영향을 주기도 한다]
# 처음 답
select activity_date as day,
count(distinct user_id) as active_users
from Activity
group by activity_date
having datediff('2019-07-27', activity_date) <= 29 and activity_date <= '2019-07-27'
# 조건을 where 로
select activity_date as day,
count(distinct user_id) as active_users
from Activity
where datediff('2019-07-27', activity_date) <= 29 and activity_date <= '2019-07-27'
group by activity_date
- 처음엔 생각의 흐름대로 조건을 having에 넣어주었지만, where로 옮기니 결과는 같고 속도는 확실히 줄어들었음(약 200ms)
- having과 where은 같은 필터링 결과를 반환하기도 하니, 이럴땐 where에 써주는게 효율적임
2. Python 연습
Python 코드카타
[if, 연달아 수행해도 되는 것]
- if나 for문이 함수 안에서 한번만 쓰여야한다는 이상한 강박이 무의식 중에 있었던 것 같음
- 하지만 전혀 놉, 연달아 마구 써줘도 됨
- 하나의 if문의 동작이 끝나면 그 결과를 바탕으로 다음 if문이 실행되는 것
- 파이썬을 직관적인 언어로 대하자
def solution(num):
if num == 1 :
return 0
for i in range(1,501) :
if num % 2 == 0 :
num = num / 2
else :
num = num * 3 + 1
if num == 1 :
return i
return -1
[기억 저편에 가버린 while]
- 계속 for문만 쓰다보니 완전히 잊은 while
while 조건문 :
수행할 내용
- 조건이 참인 동안은 계속 반복하고, false가 되는 순간 끝나는 점을 이용
- 반복의 범위는 잘 모르겠지만 대충 조건이 안맞을 때 그 값을 return하고 싶다면 고려해볼 것
- 위의 코드는 아래와 같은 결과
def solution(num):
answer = 0
while num != 1:
if num % 2 == 0:
num /= 2
else:
num = num * 3 + 1
answer += 1
if answer == 500:
return -1
return answer
3. Python으로 데이터 분석하기
라이브 세션
[중복값 확인, keep=False 버릇을 들이자]
- df.duplicated(keep=False)를 하여 첫번째 값이나 마지막 값을 제외하지 않고, 모든 중복 행들을 추출하여 살펴보는 것을 습관화 하는걸 추천
- 모든 행들을 살펴본 후, 중복값 삭제시 첫 행을 남길지 마지막 행을 남길지 선택
[apply(), 알듯 모를듯, pandas에서 def 사용하는 방법이란다]
# 방법1
def app(x):
if x["age"] > 20:
if x["sex"] == "male":
a = "남자"
else:
a = "여자"
else:
a = "어린이"
return a
titanic["성별2"] = titanic.apply(app, axis =1)
#방법2
titanic['성별2'] = titanic.apply(lambda x : "남자" if x["sex"] == "male"
else "여자" if x["age"] > 20 else '어린이', axis=1)
- 기존에 파이썬 코드카타 문제를 풀면서 함수를 정의하던 것을 데이터프레임을 조작하는데 사용하는 방법
- apply를 통해 다양한 조작이 가능하므로 꼭 기억!!!
'데이터 부트캠프 - Today I Learned' 카테고리의 다른 글
[스파르타 내일배움캠프 / 데이터 분석 트랙] TIL(Today I Learned)_5주차_24.12.23 (0) | 2024.12.23 |
---|---|
[스파르타 내일배움캠프 / 데이터 분석 트랙] WIL(Weekly I Learned)_4주차 (0) | 2024.12.22 |
[스파르타 내일배움캠프 / 데이터 분석 트랙] TIL(Today I Learned)_4주차_24.12.19 (1) | 2024.12.19 |
[스파르타 내일배움캠프 / 데이터 분석 트랙] TIL(Today I Learned)_4주차_24.12.18 (3) | 2024.12.18 |
[스파르타 내일배움캠프 / 데이터 분석 트랙] TIL(Today I Learned)_4주차_24.12.17 (3) | 2024.12.17 |