Today's Goals
1. SQL 꾸준한 연습
2. 파이썬 익숙해지기 - 파이썬 코드카타
3. 파이썬 분석 이해하기 - 파이썬 시각화 강의, 전처리&시각화 숙제와 실습
코드카타를 풀다보니 코딩에서 필요한 수학적 사고를 알 것 같고.... 하지만 나만 없지 그 사고력... 주륵
어쨌든 pandas를 쓰기 시작하고 시각화를 시작하니 좀 재밌다...?
나, 우매함의 봉우리에 도착했을지도 ㅋ
![](https://t1.daumcdn.net/keditor/emoticon/niniz/large/009.gif)
1. SQL 연습
SQL 코드카타
[문자 조건 해당 여부에 따른 집계는 숫자로 변환하면 간단]
- id마다 확인 요청을 받은 총 수와 실제로 확인한 총 수에 대해 비율로 나타내라는 문제
- 그렇다면 확인 여부 테이블에서 id별 총 건수도 세고, action 컬럼이 confirmed 인 컬럼도 세야겠다가 나의 논리 구조
- 가입 명단에는 있지만 확인 요청을 받지 않았을 수도 있으니 고객 명단에 싹다 left 조인 해서 구하자고 생각
with confirm_count as (
select user_id, count(user_id) as confirm_count
from Confirmations
where action = 'confirmed'
group by user_id
),
total_count as (
select user_id, count(user_id) as total_count
from Confirmations
group by user_id
)
select a.user_id,
case
when b.user_id is null or c.user_id is null then 0
else round(c.confirm_count/b.total_count,2)
end as confirmation_rate
from Signups a
left join total_count b on a.user_id = b.user_id
left join confirm_count c on a.user_id = c.user_id
아 쿼리 한번 길다- 아래는 모든 테이블을 left join 했을때의 결과임 > null 값을 확인할 수 있고, 이 때 어떻게 처리할지 case를 나누면 됨
하지만 역시 세상엔 천재가 많다- 이 쿼리 엄청나게 줄이는 방법 : confirmed 조건을 판별하여 1,0으로 바꾸고 집계함수 sum을 쓰는것
# 답안1 -- 처리 속도 4
select a.user_id,
round(avg(if(b.action='confirmed',1,0)),2) as confirmation_rate
from Signups a left join Confirmations b on a.user_id = b.user_id
group by a.user_id;
#답안2 -- 처리 속도 3
WITH CTE AS (
SELECT s.user_id,
COUNT(*) AS Total,
SUM(IF(c.action = 'confirmed', 1, 0)) AS ConfirmedAmount
FROM Signups s LEFT JOIN Confirmations c ON s.user_id = c.user_id
GROUP BY s.user_id
)
SELECT c.user_id,
ROUND(c.ConfirmedAmount / c.Total, 2) AS Confirmation_Rate
FROM CTE;
#답안3 -- 처리 속도 1
SELECT s.user_id,
ROUND(SUM(IF(c.action = 'confirmed', 1, 0)) / COUNT(1), 2) AS confirmation_rate
FROM signups s LEFT JOIN confirmations c ON s.user_id = c.user_id
GROUP BY s.user_id;
#답안4 -- 처리 속도 2
SELECT DISTINCT(s.user_id),
ROUND(SUM(IF(c.action = 'confirmed', 1, 0)) OVER (PARTITION BY s.user_id) /
COUNT(*) OVER (PARTITION BY s.user_id), 2) AS confirmation_rate
FROM signups s LEFT JOIN confirmations c ON s.user_id = c.user_id;
- 위의 답안 4가지 모두 조건 여부를 1,0으로 변환하는 과정을 거침
- 조건 여부 기반의 컬럼 조작은 항상 숫자로 바꾸어 활용할 수 있다는 것을 잊지 말아야 함
[a % b를 뜻하는 함수 MOD]
- MOD(i,2) = 1 : i % 2 = 1 과 같은 뜻
- mod 함수는 나누기의 나머지를 뜻하는 것으로, a%b 와 mod(a,b) 와 a mod b 는 모두 같은 뜻임
2. 파이썬 자신감 회복기
Python 코드카타
[각 자릿수 더하기, 10,100,....으로 열심히 나눌 필요가 없었네]
- 자연수 N에서 각 자릿수를 구하기 위해서 10, 100,... 으로 나누려면 N이 몇자리 수인지 처음부터 알아야함
- 놀랍게도 숫자 형태는 문자로 바꿀 수 있고, 각 숫자 문자는 다시 숫자 형태로 바뀔 수 있음
def solution(n):
answer = 0
n_to_str = str(n)
for i in n_to_str :
answer += int(i)
return answer
- 숫자 > 문자 > 숫자로 바꾸면 각 자릿수를 자른 효과, 모두 더해주면 원하는 답을 얻을 수 있음
[조건에 맞는 최소값, min도 쓰고 싶고 그냥 알아서 멈췄으면 좋겠기도 하고? - break를 잊지말기]
- 자연수 n이 주어지고, 나머지가 1이 되는 약수 중 최소값을 찾는데 두가지 방법이 머리에 혼재됨
- 처음 생각 > 나머지가 1인 조건을 걸어주고, answer = min(x)라고 하면 반복수행 중 조건에 맞는 첫 약수가 나올 때 알아서 멈출 것이라 생각함
- min의 사용법은 x값에 대한 리스트가 있는 상태에서, 그 중 최소값을 찾아주는 것임
- break : 반복문 수행 중 조건에 맞는 첫번째 값이 나오는 경우 반복을 멈추는 방법
- 리스트는 어렴풋이 머리에 떠오른 방법이지만, break는 전혀 상상도 못함 >> 반복문 조작 문법 익숙해지기(break, continue, pass)
[정수 x부터 x 간격 만큼 n개를 출력하는 리스트?]
def solution(x, n):
answer = []
if x < 0 :
for i in range(x,x*n-1,x) :
answer.append(i)
elif x > 0 :
for i in range(x, x*n+1, x) :
answer.append(i)
else :
for i in range(n) :
answer.append(0)
return answer
- range 함수에 a부터 b까지 s 간격으로 출력하는 기능이 있다는 것이 생각남
- 다만, x가 자연수가 아닌 정수이기 때문에 경우를 나눌 필요가 있었음
- 다른 풀이는 보던 중, 해당 문제를 수학적으로 생각하면 코드가 훨씬 쉬어진다는 것을 알게됨
- x부터 x 간격만큼 n개를 나타내는 것은 구구단의 x단을 n까지만 수행하는 것
def solution(x, n):
answer = []
for i in range (1,n+1):
answer.append(x*i)
return answer
알고리즘에서 문제를 수학 공식으로 생각하는 것이 이렇게 중요합니다
3. 파이썬 분석 이해하기
시각화 강의
[그래프의 전체 크기를 조절하는 두가지 방법]
# 방법1
plt.figure(figsize=(8,6))
plt.plot(df['column1'], df['column2'])
plt.show()
# 방법2
fig, ax = plt.subplots(figsize=(8.6))
ax = df.plot(x='A', y='B', ax=ax)
#or
#ax.plot(df['column1'], df['column2'])
plt.show()
[히스토그램의 bin]
- hist(~ , bins = 30) : 분포도를 그릴 때, 총 30개의 구간으로 나누어 그린다는 의미
시각화 강의 숙제
[그래프를 그리는 방법]
#방법1
plt.plot(df['column1'], df['column2'])
plt.bar(df['column1'], df['column2'])
plt.hist(df['column1'])
#방법2
ax = df.plot(x='column1', y='column2', ax=ax)
ax = df.plot.bar(x='column1', y='column2', ax=ax)
ax = df['column1'].plot.hist(ax=ax)
#방법3
ax.plot(df['column1'], df['column2'])
ax.bar(df['column1'], df['column2'])
ax.hist(df['column1'])
- ax는 꼭 fig, ax = plt.subplots()와 함께 사용(도화지를 먼저 그려주는 역할)
- 방법2를 사용할 땐, ax=ax 꼭 써야함
- hist의 경우 2번에서 예외가 있어서 꼭 유의!
[subplots() 그게 대체 뭔데]
- plt.plot은 하나의 그래프가 그려지는 것
- subplots()은 한번에 여러 그래프를 띄우고 싶을 때 쓰는 것
- 그래서 적용 범위가 더 큰, fig, ax = plt.subplots의 사용법에 익숙해지는게 좋음(하나의 그래프만 그릴때도)
[nXm 행렬로 그래프를 띄우는 방법]
- 2행1열 혹은 1행2열의 subplot을 그리는 경우, fig, (ax1, ax2) 방법을 써도 가능
- 하지만, 2행 2열 이상의 subplot이 되는 순간 fig, ((ax1,ax2),(ax3,ax4)) 형식이 되기 때문에 복잡해짐
fig, ax = plt.subplots(n, m)
ax[0,0]
ax[0,1]
...
ax[0,m]
...
ax[n,m]
- 위 사용법을 더 익숙하게 공부하도록 하자
[subplots() 공부 참고]
https://blog.naver.com/rising_n_falling/222467744170
Matplotlib - plt.subplot()과 plt.subplots() 비교
안녕하세요. '라이징n폴링'입니다. 이번 글에서는 Matplotlib 라이브러리 사용 시, "plt.s...
blog.naver.com
https://m.blog.naver.com/youji4ever/222687250059
[데이터시각화] matplotlib : subplots() 함수의 fig와 ax의 역할 이해하기, axes 제어 방식이 좋은 이유는?
matplotlib을 맨 처음 사용하기 시작할 때에는 잘하는 사람들 코드 따라해보느라 그냥 어떤 원리로 작동하...
blog.naver.com
전처리 강의 숙제
[pandas, 조건에 맞는 행만 필터링 하는 방법]
- df[df['컬럼'] > 1] : 조건 자체를 데이터프레임[]으로 묶으면 필터링 된 결과를 볼 수 있음
[reset_index() 사용 여부의 차이]
- reset_index()를 하지 않는 경우, 결과는 1차원 데이터 구조로, 인덱스와 값만 가지는 형태인 series 객체로 반환됨
- reset_index()를 하는 경우, 기존에 index였던 day 값이 컬럼으로 변환되고 새로운 index가 설정되며, dataframe 객체로 반환됨
- 컬럼을 조작하기 위해서는 꼭 reset_index()를 통한 데이터프레임 변환이 필요함
전처리 강의 추가 실습 - 메소드 공부
[null값 처리]
- df.isnull().sum() : 데이터프레임의 전체 값에 대해 null 값을 찾아 T/F를 반환하고, sum을 통해 각 컬럼별 null의 갯수 반환
- df.dropna() : null값이 있는 행을 모두 삭제함
[중복값 처리]
- df.duplicated() : 전체 컬럼에 대해 각 행별로 중복 여부를 확인해 T/F 반환
- df.duplicated(subset = ['컬럼1', '컬럼2', ...]) : subset에 해당하는 컬럼 조합에 대한 중복 여부 판별
- df.duplicated().sum() : 전체 컬럼에 대한 중복 행의 갯수
- df.drop_duplicates() : 전체 컬럼에 대한 중복 행 삭제
- df.drop_duplicates(subset = []) : subset 컬럼 조합에 대한 중복 행 삭제
- 중복행이 삭제될 때는 첫번째 행을 남기고 나머지가 삭제되는 것이 기본값, keep인수를 통해 첫 행을 남길지 마지막 행을 남길지 정할 수 있음(keep='first' or keep='last')
- 중복행 개수 또한 원본행을 제외한 나머지 똑같은 행의 개수임
[컬럼 값을 다른 형식으로 변환하기]
- pd.to_datetime(df['컬럼']) : 날짜 형식으로
- df['컬럼'].astype(dtype 종류) : 특정 dtype으로 변경하는 것(int, float 등등)
[shape]
- df.shape : 데이터프레임의 형태 반환(n,m)
- df.shape['컬럼'] : 컬럼(데이터프레임)의 행의 수 반환
[사분위수 찾기]
- df['컬럼'].quantile(0.25) : 1사분위 수(2사분위는 0.5, 3사분위는 0.75 입력)
[정규화 하기 - min / max]
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
df['새 컬럼'] = scalar.fit_transform(df[['정규화 할 컬럼']])
- min max 정규화는 특정 컬럼의 값이 실수로 이루어졌을 때, 최소값을 0 최대값을 1로 하여 그 사이 값으로 정규화 해주는 것
'데이터 부트캠프 - Today I Learned' 카테고리의 다른 글
[스파르타 내일배움캠프 / 데이터 분석 트랙] 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.16 (1) | 2024.12.16 |
[스파르타 내일배움캠프 / 데이터 분석 트랙] WIL(Weekly I Learned)_3주차 (1) | 2024.12.15 |
[스파르타 내일배움캠프 / 데이터 분석 트랙] TIL(Today I Learned)_3주차_24.12.13 (0) | 2024.12.15 |