다 맞을줄 알았는데 두개나 ㅋ 틀림 ㅋ 잉
3개중에 하나 맞은걸로 만족..한다 ㅜㅜㅜ
으악 근데 큐씨씨 할때마다 아쉬운 점
내가 뭘 맞추고 틀렸는지 말해주셨으면 좋겠다.. (번호만요..많은거바라는거 아니지않습니까..!!)

진짜.. 복습을 너무 안해서 기본적인것도 기억이 안났다 ㅠㅠ
문자열 substring 써서 날짜표현하는거..
내 코드
with q1 as
(select category as ca, id
from calls
where category ='n/a' or category is null),
q2 as
(select count(c.category) as a, count (q1.ca) as b
from calls as c
left join q1 on c.id = q1.id
where substring(call_date,1,10) <= '2024-04-15')
select round(b / a * 100, 1)
from q2
나는 11줄이나 나왔는데 왜 정답코드는 5줄이냐고 ~
정답코드
select
round((sum(if(category = 'n/a' or category is null, 1, 0))/
count(1)) * 100, 1) as uncategorized_call_pct
from calls
where date_format(call_date, '%Y-%m-%d') < '2024-04-16'
일단 틀린점... count(ca)는 null값을 포함하지 않는다..
count(1)하면 전체 행 수를 세는 반면 count(ca)하면 null값을 세지않음...
효율 측면에서 substring과 with문이 있다.
개선할 점..
1. substring 사용
substring을 사용하면 같은 값처럼 보이지만 date_format을 쓰는게 더 정확하다.
date_format(call_date, '%Y-%m-%d') < '2024-04-16'
개선할 점 2. with문 사용
q1은 하나의 열 값을 체크하는거라 굳이 join 안해도 됨!
ㅠㅠ 코드카타 열심히 해야겠다...
with문 쓰고나서 너무 코드를 길게 만들고 있는 것 같은데 주의해야겠다

내 코드
with q1 as
(select user_id, event_type
from app_events
where event_type = 'order'),
q2 as
(select a.user_id, a.event_type, age_bucket,
count(case when a.event_type = 'view' then 1 end) as v,
count(case when a.event_type ='order' then 1 end) as o
from app_events as a
join q1 on a.user_id = q1.user_id
join user_profiles as u on a.user_id = u.user_id
group by age_bucket)
select age_bucket, round((o / (v+o)*100),2) as conversion_rate
from q2
order by 1
와 이제보니까 가입자 조건 안걸었다...
진짜 문제읽으라고 ㅜㅜㅜㅜ 바부야
정답코드
select up.age_bucket,
round((sum(if(event_type = 'order', 1, 0)) / count(1)) * 100, 2) conversion_rate
-- 분자가 order한 수
-- 분모가 order / view 한
from user_profiles up
join app_events ap
on up.user_id = ap.user_id
where up.signup_date >= '2023-01-01'
and event_type in ('order', 'view')
group by 1
order by 1
select문에 count(1)이 있길래 조건 걸어줘야하는거 아닌가 했더니
where절에 and 뒤에 in()이 있었다. 와 진짜 안한지 너무 오래돼서 ㅠㅠ 정말 다 까먹었다
in은 값이 조건안에 있는가를 확인하는 연산자
or을 여러번 쓰는걸 간단하게 줄여줌.

내 코드
with q1 as
(select user_id, order_datetime,
row_number() over (partition by user_id order by order_datetime) as c
from user_orders),
q2 as
(select user_id, c, order_datetime
from q1
where c = 10),
q3 as
(select q1.user_id, q1.order_datetime as f, q2.order_datetime as e
from q1
join q2 on q1.user_id = q2.user_id
where q1.c = 1)
select user_id, datediff(e,f) as days_to_power_user
from q3
order by days_to_power_user
limit 1
정답코드
select user_id,
datediff(tenth_ordertime, order_datetime) days_to_power_user
from (
select user_id
, order_datetime -- n번째 주문
, lead(order_datetime, 9) over
(partition by user_id order by order_datetime) as tenth_ordertime -- n+9번째 주문
, row_number() over (partition by user_id order by order_datetime) as seq -- n
from user_orders
) a
where seq = 1 and tenth_ordertime is not null
order by 2
limit 1
이거 하나 맞췄다..!!
진짜 튜터님 코드 보면 아맞다의 연속임 ㅋㅋ..흐어어
나는 10개를 다 뽑았는데 lead()함수로 현재 주문에서 9개 뒤 (=10번째 주문)를 뽑은것.
statistics csv 파일을 읽고, Category 기준 Customer ID 컬럼은 Count, Purchase Amount(USD) 컬럼은 Sum 연산을 진행해주세요. 동시에 2가지 연산을 진행해주세요. (한번의 group by)
한번에(동시에) 두가지 연산하는 법 저번 과제에서 튜터님이 알려주셨는데
여전히 기억안나서 다시 확인하러 감.. agg였던거같은데 어떻게 쓰는지 잘 기억나지 않았다
DataFrame.agg({
'컬럼1': 함수 또는 [함수들],
'컬럼2': 함수 또는 [함수들],
...
})
df.agg({
'점수': ['mean', 'max'],
'시간': 'sum'
})
agg함수는 딕셔너리 형태로 컬럼과 함수를 넘겨줘야함!
함수 쓸 때도 '' 쓰는거 잊지말기
괄호 {}, (), [] 안에서는 마음껏 줄 나눠도 된다
Expanding 메서드를 이용하여, Purchase Amount (USD) 의 누적 합을 계산해주세요.
그리고 결과값을 df의 “Purchase Amount (USD)_누적” 컬럼으로 새롭게 지정해주세요. 그리고 Purchase Amount (USD) 과 함께 보여주세요.
expanding을 사용하라 했는데 기억이 ㅋㅋ 안나는데 어떡해요..
(standard 3회차)
df.expanding(min_periods=1, axis=0, method='single').추가메서드()

성별 Review Rating 에 대한 평균과 중앙값을 동시에 구해주세요. 결과는 소수점 둘째자리까지 표현해주세요. 그리고 이에 대한 해석을 간략하게 설명해주세요.
평균과 중앙값 보고 해석하기
T-TEST
성별, Review Rating 컬럼에 대한 T-TEST 를 진행해주세요.
- 해당 데이터셋의 컬럼들은 정규성을 만족한다고 가정하겠습니다.
(T-TEST 진행시, equal_var=True 로 지정해주세요.)
- 귀무가설과 대립가설을 작성해주세요.
- t-score, P-value 를 구해주세요. 단, t값의 부호는 어느 집단의 평균이 더 높은지에 대한 방향성에 대한 내용이므로, 아래와 같이 해석해주세요.
- t > 0: 첫 번째 그룹 평균이 더 큼
- t < 0: 두 번째 그룹 평균이 더 큼
귀무가설: 성별과 Review Rating은 관련이 없다
대립가설: 성별과 review rating은 관련이 있다. (여자가 크다?..)
관련으로 가설을 짓는게 맞나..?
급.. 헷갈리는점 남자가 여자보다 review rating을 높게 준다 이런식으로 하면 안된다고 했던거같은데... 아티클쪽이었던듯
# 오류코드
fr = df['Gender' == 'Female']['Review Rating']
mr = df['Gender' == 'Male']['Review Rating']
# 독립표본 t검정
t_stat, p_val = stats.ttest_ind(fr, mr)
print(f"T-Statistic: {t_stat}, P-value: {p_val}")
# 정답코드
fr = df[df['Gender'] == 'Female']['Review Rating']
mr = df[df['Gender'] == 'Male']['Review Rating']
# 독립표본 t검정
t_stat, p_val = stats.ttest_ind(fr, mr)
print(f"T-Statistic: {t_stat}, P-value: {p_val}")
이바보야... 오류나서 Gender = Female도 해봄 ㅋㅋ
'Gender' == 'Female' 이건 항상 False! 당연함 문자열 비교임 ;
T-TEST가 뭐더라.....
두 집단의 평균이 통계적으로 차이가 있는지 확인하는 방법
관찰한 두 그룹의 평균 차이가 우연히 생긴 차이인지, 진짜로 의미 있는 차이인지 확인
t값이 크다 = 평균 차이가 크다
T-test에서 귀무가설과 대립가설
T-Statistic: -0.5097147504896427
t값이 음수이므로 남자의 평균리뷰 점수가 더 크다
귀무가설이 참일때, 이것(관측)이 운으로 생길 확률
귀무가설이 참일때, 관측값(또는 더 극단적인 값)이 일어날 확률 = p-value
p값이 작다 = 귀무가설이 참일 때, 관측값(또는 극단적인 값)이 일어날 확률이 작다 -> 귀무가설 기각
귀무가설이 참 = 남자와 여자의 평균차이 0
우리가 관측한 평균 차이 = 0.05
만약 진짜로 두 그룹의 평균이 똑같은데(귀무가설이 참인데)
샘플을 우연히 뽑았을 때 평균 차이가 0.05, 또는 그 이상 벌어질 확률이 얼마나 될까?가 P-value
P-value: 0.6102801734916257
평균의 차이가 0.05, 또는 그 이상 나타날 확률이 60%다.(흔한 일이다)
이는 유의수준 0.05보다 훨씬 높다 -> 귀무가설을 기각할 수 없다(근거가 없음)
귀무가설(여자와 남자의 평균 리뷰 점수는 같다)을 기각하는게
의견주장(여자와 남자의 평균 리뷰 점수는 다르다)에 근거가 되는데
p-value가 높다= 귀무가설이 참일때 관측값(또는 극단적인 값)이 나타나는 일이 흔하다
= 통계적으로 유의미한 차이(평균 점수 차이)가 없다
p-value가 0.61로 유의수준 0.05보다 크기 때문에,
관측된 평균 차이(0.05)는 ‘우연히 생길 수 있는 흔한 수준의 차이’이며,
통계적으로 유의미하다고 볼 수 없다.
→ 따라서 귀무가설(남자와 여자의 평균 점수는 같다)을 기각할 수 없다.
통계 3주차 유의성검정
두 집단 간 평균 차이의 크기와 방향을 나타냄
독립표본 vs 대응표본으로 나뉨. 대응 = 사전/사후 평균 비교
p-값: 귀무가설이 참일때, 관찰된 결과 이상으로 극단적인 결과가 나올 확률.
p_val이 0.05보다 낮으면 우연히 벌어진 일이 아님을 시사.
p-가 유의수준보다 작다면 귀무가설을 기각한다(= 귀무가설이 틀렸다고 보고 대립가설을 채택한다.)