본문 바로가기
서비스 기획/✏️ 서비스 기획

주니어 PM의 SQL & 파이썬 실무 적용기

by 림뽀 2022. 11. 21.
반응형

올해 8월, 지금껏 배웠던 SQL & 파이썬을 실무에 적용할 기회가 왔습니다. 약 4개월간의 저의 SQL & 파이썬 실무 적용기를 하나의 글로 정리해보고자 합니다. 초보의 관문을 지난 지 오래인 전문가는 모르는 초심자의 고민을, 다른 초심자는 답할 수 있다고 생각해요. 초보의 관문을 지나는 저와 다른 모든 PM 동료에게 이 글을 바칩니다.

 

이 글은 두 가지 질문에 답변을 드려요.

 

Q1. PM이 SQL & 파이썬을 배우면 뭐가 좋아요?

Q2. SQL은 그렇다 쳐도... 파이썬까지 알아야 할까요?

 

저도 1년 넘게 사내/사외 교육으로 SQL & 파이썬을 배우면서, '내가 굳이 시간을 들여서 이걸 공부할 필요가 있을까?'라는 고민이 있었어요. 배운 걸 바로 실무에 적용할 일이 없었기 때문이죠. 사내 데이터 분석 시스템도 있고, ES의 data visualization 툴인 KIBANA도 있었으니까요.

 

하지만 쉬운 툴에는 한계가 있습니다. SQL & 파이썬만큼 데이터 분석에 자유도가 보장되지 않아요. 필터의 개수도 한정되어있고, 테이블을 합치는 것도 제한되었거든요. 연차가 쌓이고 복잡한 데이터 추출이 필요해질수록 새로운 껍데기를 찾는 소라게처럼 더 크고 자유로운 집이 필요해졌습니다. 그렇게 올해 8월, 신규 프로젝트에 투입되며 SQL & 파이썬을 실무에서 사용하게 되었습니다.

 

저의 개인적인 경험은 여기까지 말씀드리고, 이제 두 질문에 대한 답변을 드려볼게요.

 

 

Q1. PM이 SQL & 파이썬을 배우면 뭐가 좋아요?

1) 당연한 말이지만, 개발자가 짠 쿼리/코드를 이해할 수 있게 됩니다.

PM의 요청사항이 복잡해질수록 개발자가 PM의 요구 사항을 100% 이해하기 어려워져요. 게다가 개발자도 사람이니 실수를 할 수 있죠. PM이 쿼리를 이해한다면, 정확한 데이터를 얻게 될 확률이 높아집니다. 쿼리를 돌리기 전에 검토하고 오류를 발견할 수도 있고, 돌린 후에 문제가 있는 쿼리를 짚어낼 수도 있죠.

 

2) 개발자가 짜준 쿼리를 활용할 수 있습니다.

간단한 조건은 PM이 직접 코드를 수정해서 돌릴 수 있습니다. 그렇게 되면 조건을 바꾸고 싶을 때마다 개발자에게 매번 따로 부탁할 필요 없습니다. 예를 들어, 11월 19일의 로그를 추출하는 쿼리를 11월 20일로 바꾸고 싶다면 날짜 조건만 바꾸면 됩니다. 이 정도는 SQL 초보도 금방 수정할 수 있어요.

 

3) PM이 궁금한 게 있으면 직접 찾을 수 있습니다.

PM이 신규 기능을 출시했습니다. 신규 기능 A를 이용하는 사람이 얼마나 있는지 빨리 알고 싶다고 해볼게요. 로그 정의서만 있다면 간단한 SQL 쿼리를 통해 PM이 데이터를 추출할 수 있습니다. 파이썬을 모르더라도 간단한 SQL 쿼리로 데이터를 추출한 후 엑셀에서 가공하면 됩니다.

 

 

Q2. SQL은 그렇다 쳐도... 파이썬까지 알아야 할까요?

필수는 아닙니다. 대부분의 기능은 엑셀도 제공하기 때문입니다. 그렇다면 파이썬을 배울 필요가 없을까요?

 

저는 이번에 신규 서비스 데이터 분석 프로젝트에 투입되고 분석 역량을 한 단계 올리기 위해서 파이썬을 배우는 편이 좋겠다고 생각했어요. 가장 큰 이유는 개발자가 데이터 추출/분석 쿼리를 파이썬 코드로 줬기 때문이에요.

 

파이썬(pandas)은 SQL보다 연산 자유도가 높습니다. 데이터를 대량으로 처리하고, 복잡한 수식을 적용하기에 용이해요. 데이터 후가공을 위해 파이썬을 사용하는 개발자가 많기 때문에 Q1에서 답변한 장점을 십분 발휘하기 위해선 파이썬까지 이해할 필요가 있더라고요.

 

제가 생각한 파이썬의 장점을 4가지로 정리했습니다. 이번엔 Q1의 답변보다 더 구체적으로, 코드 단위에서 설명드릴게요.

 

1) 파이썬이 SQL보다 테이블을 합치기에 용이합니다.

'테이블을 합친다'는 것은 엑셀로 치면 VLOOKUP의 기능을 뜻해요. SQL로는 두 개 이상의 열을 기준으로 테이블을 연결할 수 없지만, 파이썬(pandas)은 가능합니다. 편의상 pandas 데이터프레임을 '테이블'로 칭하겠습니다.

 

예를 들어, 우리 OTT 앱에 처음 진입한 사용자의 첫 진입일의 평균 시청시간을 구하고 싶다고 해볼게요. 그러면 처음 진입한 사용자의 첫 진입일 정보가 있는 테이블(first_users_df)과 각 사용자의 날짜별 시청시간 테이블(play_duration_df)을 합쳐야 합니다.

 

- first_users_df의 데이터 열: 날짜(dt), user_id

- play_duration_df의 데이터 열: 날짜(dt), user_id, 평균 시청시간

 

사용자별 첫 진입일의 평균 시청시간을 구해야 하므로, 두 테이블을 합칠 때 날짜(dt)와 user_id가 동시에 일치해야 합니다. 파이썬에서는 pandas의 merge 기능에 on=['dt', 'user_id'] 조건을 적으면 됩니다. 그러나 SQL에서는 테이블 조인 시 on에 두 개 이상의 조건을 적으면 에러가 발생합니다.

 

merge_df = pd.merge(left= new_user_df, right= play_duration_df, how='inner',
                  on=['dt','user_id'], sort=False)
 
merge_df.groupby('dt').sum_duration.mean()

 

2) 파이썬에 집계 기능이 더 많습니다.

SQL에서는 그룹별로 count, sum, 평균(avg)을 집계하는 기능을 기본으로 제공하지만, 중앙값(median)은 제공하지 않습니다. 사용자별 시청시간의 중앙값을 간단하게 구하고 싶다면 파이썬이 적합합니다.

 

merge_df.groupby('dt').sum_duration.mean() #평균
merge_df.groupby('dt').sum_duration.median() #중앙값

 

3) 파이썬은 테이블의 부분 집합 활용에 탁월합니다.

파이썬에서는 테이블을 한 번 정의하면 비교적 쉽게 조건에 맞는 부분 집합 테이블을 가져올 수 있습니다. 반면, SQL에서는 with절로 테이블을 별도로 정의한 후에 부분 집합을 만들거나, 서브쿼리(쿼리 안의 쿼리)를 사용해야 합니다. 요구사항이 많을수록 서브쿼리가 많아지고 쿼리가 복잡해지죠.

 

예를 들어, 일별로 "모든 사용자의 평균 시청시간"과 "1분 이상 시청한 사용자의 평균 시청시간"을 비교하고 싶다고 해볼게요.

 

SQL에서는 사용자별 일일 시청시간 테이블을 별도로 정의합니다. 해당 테이블을 활용해서 (2-1) 전체 사용자의 일일 평균 시청시간 테이블과 (2-2) 1분 이상 시청한 사용자의 일일 평균 시청시간 테이블을 날짜 기준으로 join 했습니다.

 

-- (1) 사용자별 daily 시청시간 합계 테이블 정의
with table1 as
(
    select dt, user_id, sum(watch_duration) as sum_duration
    from raw_watch_table
    where event_mode = 'PLAY'
    group by dt, user_id
)
 
-- (2) table1 활용해서 평균 시청시간 구하기
select t1.dt, avg_duration_all, avg_duration_60 from
(
    select dt, round(avg(sum_duration),2) as avg_duration_all 
    from table1 
    where sum_duration >= 0
    group by dt
) t1 -- (2-1) 전체 사용자의 평균 시청시간
left join
(
    select dt, round(avg(sum_duration),2) as avg_duration_60 
    from table1
    where sum_duration >= 60 
    group by dt
) t2 -- (2-2) 1분 이상 시청한 사용자의 평균 시청시간
on t1.dt = t2.dt
order by dt

 

같은 결과를 파이썬으로 얻기 위한 코드입니다. 먼저, AthenaGetQuery를 사용해서 SQL로 추출한 데이터를 테이블로 만듭니다. (1) 과정에 해당하는 쿼리는 동일합니다. 그 후 모든 날짜를 for문을 돌려서 각 날짜별로 (2-1) 전체 사용자의 평균 시청시간, (2-2) 1분 이상 시청한 사용자의 평균 시청시간을 구했습니다.

 

#(1) 사용자별 daily 시청시간 합계 df 만들기 (SQL --> DataFrame)
conn = athena_connection()
sql = f"""
    select dt, user_id, sum(watch_duration) as sum_duration
    from raw_watch_table
    where event_mode = 'PLAY'
    group by dt, user_id
"""
play_df = AthenaGetQuery(conn, sql)

#(2) 위 df 활용해서 평균 시청시간 구하기
df = pd.DataFrame()
for d in sorted(play_df.dt.unique()):
    target_df = play_df[play_df.dt == d] #계산할 target 일자로 필터링
    df = df.append(pd.DataFrame([[d, target_df.sum_duration.mean().round(2), #(2-1) 전체 사용자의 평균 시청시간
      target_df[target_df.sum_duration>=60].sum_duration.mean().round(2)]])) #(2-2) 1분 이상 시청한 사용자의 평균 시청시간
df.columns = ['dt', 'avg_duration_all', 'avg_duration_60']
df

 

길이나 복잡도상 별 차이가 없어 보이는 것 같기도 하네요. 그러나 파이썬은 전체 데이터 테이블에 해당하는 play_df의 부분 집합인 (2-1)과 (2-2)을 각 한 줄로 표현할 수 있다는 것이 생각보다 큰 장점입니다. 부분 집합 정의에 용이하다는 파이썬의 장점은 데이터 추출 요구사항이 복잡해질수록 빛을 발합니다.

 

예를 들어, 1분 이상 시청한 사용자만이 아닌 10초, 20초, 30초, 40초, 50초, 그리고 1분 이상 시청한 사용자별 평균 시청시간을 알고 싶다면 SQL에서는 sum_duration >=10 부터 60까지의 테이블을 모두 수동으로 만들고, left join을 5번 해야겠죠. 반면 파이썬에서는 for문으로 조건을 자동으로 넣고 결과를 한 번에 볼 수 있습니다.

 

#(2) 위 df 활용해서 평균 시청시간 구하기
for d in sorted(play_df.dt.unique()):
    target_df = play_df[play_df.dt == d] #계산할 target 일자로 필터링
    for i in range(10,61,10):
    	result_df[i] = target_df[target_df.sum_duration>=i].mean()
    result_df['dt'] = d
    df.append(result_df.loc['sum_duration'])
df = df.set_index('dt', drop=True)
df

 

코드 결과 (duration 값 모자이크 처리)

 

4) SQL은 쿼리로 하나로 한 개의 csv 파일만 추출 가능한 반면, 파이썬은 한 번에 여러 파일을 뽑을 수 있습니다.

파이썬 pandas의 to_csv 함수를 사용하면 하나의 코드만 돌려도 여러 개의 csv 파일을 추출할 수 있습니다. 쿼리를 수동으로 여러 번 돌리고 기다릴 필요가 없어, 일을 더 빠르게 처리할 수 있습니다.

 

df.to_csv('result_by_date.csv')
result_df.to_csv('result_by_min_duration.csv')

 

 

나가면서

사실 PM이 쿼리를 처음부터 다 짜기는 어렵죠. 데이터 분석 전문가가 아니니까요. PM이 개발자만큼 쿼리 작성에 시간을 쏟을 수도 없는 노릇입니다. PM이 더 잘해야 부분은 데이터 추출과 가공 이후의 과정입니다. 데이터 속 의미를 읽어내고 글과 그래프로 결과를 정리한 후 협업하는 사람들에게 구두로 공유하는 과정 말이에요.

 

그러니까 PM의 SQL&파이썬 실력은 개발자가 짜준 쿼리/코드를 이해하고, 조건에 맞게 변형하고 조합할 수 있는 수준이기만 해도 업무의 질이 급상승한다고 생각해요. 다른 사람에게 부탁하는 일도 일이기 때문이죠. 개발자가 아무리 똑똑해도 내 마음을 독심술사처럼 모두 다 읽어낼 순 없으니까요.

 

저는 시간이 날 때 개발자가 짜준 쿼리/코드를 일부분씩 떼서 돌리는 방식으로 역량을 개선하고 있어요. 그렇게 하면 SQL, 파이썬 수업을 들을 때보다 실무 맞춤형 학습이 가능하고, 쿼리/코드를 내가 원하는 조건에 따라 어떻게 변형하고 조합하면 되는지 이해할 수 있더라고요. 연습량이 늘면 언젠가 능수능란하게 코드를 다룰 수 있겠죠.

 

데이터 분석으로 머리를 싸매는 우리 모든 PM 분들 화이팅입니다! 저는 그럼 다음에 다른 주제로 찾아올게요. 다음 글에서 또 만나요. :)

 

PM's SQL & 파이썬 실무 적용기

반응형

댓글