데이터 부트캠프 - Today I Learned

[스파르타 내일배움캠프 / 데이터 분석 트랙] TIL(Today I Learned)_4주차_24.12.20

onion95 2024. 12. 20. 21:35

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를 통해 다양한 조작이 가능하므로 꼭 기억!!!