데이터 분석

[day25] SQL : Python = 1 : 9

경 민 2025. 3. 12. 21:03
더보기

👩🏻‍💻  TODAY I LEARN

📌 SQL

- 코드카타 시간제한 두고 풀기

📌 Python 

- 라이브세션 복습

- 개인 과제 4,5번

오전에 SQL 1시간 정도 공부하고

나머지 10~11시간은 전부 파이썬 공부했다. 허허 ^.^

파도파도 계속 나오는 파이썬 함수.. 매서드..

+ pandas까지

 

솔직히 정말 어렵다.

익숙해지면 SQL보다 Python을 더 많이 쓴다고 하니

익숙해질 수밖에 ㅎ

 

외우려고 하지말고

'이런 게 있군. 이해했음.

나중에 필요하면 검색해서 써먹어야지.'

정도로 공부하자.


1. SQL 

1-1. 코드카타 제한시간 두고 풀기 (⏰ today : 5문제 30분)

1) 코드카타 101번

Q. 상품별 가장 처음 팔린 해의 판매 정보 구하기

select 
    product_id,
    year as first_year,
    quantity,
    price
from sales
where 
    year in (
            select a.year 
            from (
                 select product_id, min(year) year 
                 from sales 
                 group by 1
                 ) a
            )
select
    product_id,
    year as first_year,
    quantity,
    price
from sales
where (product_id, year) in (select product_id, min(year) as min_year
                            from sales
                            group by product_id
                            )

 

두 쿼리의 차이는??

where 절에 서브쿼리 개수가 다르다.

in을 묶음으로 처리할 수 있었던 것이었던 것이었다. . . !


2. Python

2-1. 라이브 세션 복습

1) Dataframe의 정보 파악 🔮

  • df : df 테이블 전체
  • df.head(n) : 위에서 n번째까지 
  • df.tail(n) : 밑에서 n번째까지 
  • df.shape : 행과 열의 개수 (행 개수 , 열 개수)
  • df.dtypes : 칼럼 타입
    • int64 정수형
    • float64 실수형
    • object 혼합형
    • ...
  • df.values : 행들의 배열 형태
    • df.tail(1).values : 마지막 1행 전체 출력
  • df.columns : 칼럼
  • df.columns.to_list() : 칼럼을 리스트 형태로

비교 예시

  • dr.isna().sum() 혹은 df.isnull().sum() : 결측치 (null값의 개수)  
  • df.info() : 테이블 기본 구조 (shape, column, non-null, dtype, ... 를 한 번에)

 

  • df.T : 행 ↔ 열  (피벗 아님)
  • df.describe() : 수치형 데이터들의 행 개수, 평균, 표준편차, 최솟값, 사분위수, 최댓값

 

2) Dataframe의 데이터 활용 🤹🏻‍♀️

1️⃣ 특정 칼럼 추출

📍컬럼 1개

  • df['user id']
  • df.iloc[:,1]
    • 칼럼 인덱스 1번의 전체 행

📍컬럼 여러개

  • df[['user id','product id']]
  • df.iloc[:,[1,4]]
    • 칼럼 인덱스 1번과 4번의 전체 행

2️⃣ 조건 주기

📍 조건 만족하는 행 + 나머지   where( )

  • df2.where(df2.['Age']>50) 
    • df2테이블의 Age 칼럼값이 50 초과인 행들을 보여주고, 50 이하이면 NaN 출력
  • df2.where((df2['Age']==50)|(df2['Age']==55))
    • df2테이블의 Age 칼럼값이 50 또는 55인 행들을 보여주고, 나머지는 NaN 출력
  • df2.where((df2['Age']==50) & (df2['Category']=='Clothing'))
    • df2테이블의 Age 칼럼값이 50이고 , Category 컬럼값이 Clothing인 행들을 보여주고, 나머지는 NaN 출력

📍  조건 만족하는 행만  [ ]

  • df2[df2['Age']>50]
    • df2테이블의 Age 칼럼값이 50 초과인 행들만 출력
  • df2[(df2['Age']==50)|(df2['Age']==55)]
    • df2테이블의 Age 칼럼값이 50 또는 55인 행들만 출력
  • df2[(df2['Age']==50) & (df2['Category']=='Clothing')]
    • df2테이블의 Age 칼럼값이 50이고 , Category 컬럼값이 Clothing인 행들만 출력

3️⃣ Grouping Groupby('그루핑기준')['집계할칼럼'].count() 혹은 .nuique()

📍  중복 제거 X  count()

  • df2.groupby('Gender')['customer id'].count()
    • Gender별 customer id 수
  • df2.groupby(['Gender','Location'])['customer id'].count()
    • Gender+Location별 customer id 수
    • 대괄호  소괄호

📍  중복 제거 O  nunique() , unique()

  • df2.groupby('Gender')['customer id'].nunique()
    • Gender별 customer id 수 (중복값 제거)
  • df2.groupby('Gender')['customer id'].unique()
    • Gender별 customer id  (중복값 제거)

 

4️⃣ 정렬하기  sort.values(ascending = True/False)

  • df2.groupby('Gender')['Age'].nunique().sort_values(ascending=False)
    • Gender별 Age 칼럼의 행수를 Gender 기준으로 내림차순 정렬

Q. 학습하다가 생긴 질문
1. 그룹핑해서 count하는 거 말고 평균,합계 등등을 구하는 방법은?
개수 - count()

합계 - sum()
평균 - mean()
중위수 - median()
min(), max() , .... 등 다양한 집계함수 사용하면 됨!
예시 ) df2.groupby('Location','Gender')['Age'].mean()

           ↪︎ 'Location','Gender' 별 'Age'의 평균
📍 한 번에 여러 집계값 보고 싶으면? -> agg
예시 ) df2.groupby('Gender')['Age'].agg(['mean','min','max'])
           ↪︎ 'Gender'별 'Age'의 평균, 최소값, 최대값

2. 정렬을 좀 더 다양하게 해보고싶다!

🔶 기본 구조

df.sort_values(by, axis=0, ascending=True, inplace=False, kind='quicksort', na_position='last', ignore_index=False, key=None)

많은 파라미터들 중에 많이 사용할 것 같은 것만 우선적으로 외워두었다.
1) by '기준이 될 컬럼'
2) ascending = True/False
3) ignore_index = True/False  
원래 인덱스 무시하고 새로 0부터 매기기 → True
원래 인덱스 그대로 가져오기 False


🔶 정렬의 다양한 방법


📍 특정 컬럼을 기준으로 정렬하고 싶을 때
1) 기준 1개
df.sort_values(by = '기준 컬럼명', ascending=True)

df.sort_values(by = '기준 컬럼명', ascending=False)
* ascending=True 생략가능
 예시) df.sort_values(by = 'Age', ascending=False)
           ↪︎ df 테이블 전체를 'Age' 기준으로 내림차순 정렬

2) 기준 여러개
df.sort.values(by = ['기준1','기준2'], ascending = [True, False])
*이 경우에는 ascending=True 생략하면 안되고, 기준마다 다 입력해줘야 함.
 by 개수랑 ascending 개수가 일치하지 않으면 valueerror가 뜬다 !
길이가 달라 ~
📍 특정 컬럼'만' 정렬해서 빼오고싶을 때
df['컬럼명'].sort_values()

* ascending=True 생략가능
예시) df['Age'].sort_values(ascending=False)
           ↪︎ df 테이블의 'Age' 컬럼만 출력하는데 내림차순 정렬

📍 그룹핑 후 그룹핑에 사용되지 않은 칼럼을 기준으로 정렬하고 싶을 때
구글링 했는데 잘 모르겠다..
혹시나 by를 넣으면 될까 싶어서 시도해봤는데 error 
나중에 다시 와서 정리해두겠음.
↪︎ 해결 완료. 아래 포스팅 2번 문항 참고 !
https://rosenps3.tistory.com/47

 


2-2. 주요 학습 포인트 ⭐️ (개인과제)

1. 딕셔너리 안에서 최댓값 찾기

- max(dict.values()) : 최댓값

- max(dict, key=dict.get) : 최댓값에 해당하는 key 값

- max(dict.items()) : key 기준 최댓값 (key,value)

 

2. 0으로 나눴을 때 에러 대처법 (try~except 말고 if~else 도 가능)

try:
  return a
except ZeroDivisionError:
  return b

 

3. 정규표현식

- [],[^],*,+,?, ... 여러 가지가 sql과 동일하다.

- 정규표현식을 사용하기 위해 re 라는 내장 라이브러리를 사용한다.

import re
p = re.compile('pattern')

 

☑️ 매서드 종류

match 문자열 처음부터 확인
search 문자열 전체에서 확인 (처음 매치되는 문자열만 리턴)
findall 문자열 전체에서 정규식과 매치되는 모든 문자열을 리스트로 리턴
finditer 문자열 전체에서 정규식과 매치되는 모든 문자열을 반복 가능한 객체로 리턴
sub 매치되는 문자열을 다른 문자열로 치환
split 특정 문자를 기준으로 문자열 분류

 

☑️ 작성법

p = re.compile('pattern')
m = p.match('문자열')
if m:
    print('Match found: ', m.group())
else:
    print('No match')

 

☑️ match / search 객체 매서드 종류

group() 매치된 문자열 리턴
start() 매치된 문자열의 시작 위치
end() 매치된 문자열의 끝 위치 **인덱스처럼 실제 위치보다 +1 값이 나옴
span() 매치된 문자열의 (시작, 끝) <- 튜플 형식