[Python] 예제로 익히는 Python - 3회차

Arin lee·2024년 10월 25일

PYTHON 자료형 짚고넘어가기!

  1. 기본 자료형
  • number: 정수와 실수 a = 1234
  • string: 문자열 str1 = 'hi'
  • boolean: 참(true) / 거짓(false) a = True
  1. 컬렉션 자료형
  • list : [] 대괄호로 정의, 수정가능, 순서 있음 list1 = [1, 2]

  • tuple: () 소괄호로 정의, 수정불가, 순서 있음 tuple1 = (1, 2)

  • dictionary: {} 중괄호로 정의, key와 value 값으로 나뉨, 수정가능, 순서 없음 dic = {"name": "jane", "age": 22, "grade": 'A'}

  • set: {} 중괄호로 정의, 순서 없음, s = {1, 2, 3}

  1. 라이브러리, 함수자료형
  • ndarray: numpy 에서 배열을 나타내주는 자료형

  • series, dataframe:pandas 에서 사용하는 자료형

    • series: 1차원 배열, 일종의 리스트 형태, 정수, 문자열, 실수 등을 포함
    • dataframe: 2차원 배열, 여러개의 series 로 구성, 서로 다른 데이터타입을 칼럼으로 가질 수 있음

2회차 실습해보기

  • CSV 파일을 통한 테이블 LOAD
# pandas 라이브러리를 활용한 csv 파일 읽기 
df = pd.read_csv("product_details.csv") # product_details.csv
df2 = pd.read_csv("customer_details.csv") # customer_details.csv
df3 = pd.read_csv("E-commerece sales data 2024.csv") # E-commerece sales data 2024.csv
  • Merge
    ;df2 의 Customer_id 가 df3 의 user_id 와 같은 의미.
    merge함수는 공통컬럼의 이름이 달라도, 같아도 사용 가능.
# 컬럼명이 같은 경우의 예시를 보여주기 위해 컬럼명을 임의로 변경해 줌
df3['Customer ID']=df3['user id']

# 컬럼명이 같을 경우, 아래와 같이 구현할 수 있습니다. 
# 디폴트값은 inner join 입니다.공통컬럼값이 합쳐져 하나의 컬럼으로 출력됩니다. 
merge_df = pd.merge(df2,df3)

#위 코드와 동일한 기능입니다. on 절을 사용할 수 있어요. 
merge_df = pd.merge(df2,df3, how='inner', on='Customer ID')

merge_df

공통컬럼에 대해 명명하지 않아도 수행이 된지만, 정확히 명명해주는게 좋기때문에 아래의 코드를 더 선호.

#테이블 변화 확인하기
df2.shape  df3.shape

*항상 변화를 확인해보는 습관을 가지는 것이 좋다.

# 기준열 이름이 다를 때
merge_df = pd.merge(df2,df3, how='inner', left_on = 'Customer ID', right_on = 'user id')

merge_df
  • Join
# 아래 데이터프레임에서의 index는 0,1,2,3 ... 을 의미 
#이름이 겹치는 게 없을때, 축을 기준으로 합집합
# 단순 조인
df.join(df3)
df를 기준으로! 
# join 방식 설정
df.join(df3, how='right')
#df3가 기준이 되는것!

-컬럼의 이름이 같으면 오류가 발생!

# join시 이름이 같은 컬럼이 있을 경우, 옵션으로 설정하여 조인 가능
# df.join(df2) << 오류가 남
df.join(df2,how='left', lsuffix='1', rsuffix='2')

*lsuffix='1', rsuffix='2' 이름이 같은것을 이런식으로 임의변경해줘라고 명령하는것.
ex)color,color->color1, color2로 변경.

# join 이후, 인덱스 정렬하기(별로 사용안함)
df.join(df2,how='left', lsuffix='1', rsuffix='2', sort=True)
  • Concat(자주 사용!)
    :디폴트 수직결합!
pd.concat([df2, df3])
#데이터프레임의 물리적 결합
#pd.concat([df1, df2], axis=0, ignore_index=True, join='inner')
#
#axis=0(디폴트) : 행, 밑으로 붙임
#axis=1 : 열, 오른쪽으로 붙임
#ignore_index=True : 인덱스 재배열
#join='inner' : null값(행과 열 등이 맞지 않아 생기는 NaN)을 제외한 교집합

# 세로로 결합
pd.concat([df2, df3], axis=0, ignore_index=True, join='inner')
#둘다 있는 값만 조인!(sql의 이너조인을 생각하면된다)

# 가로로 결합
pd.concat([df2, df3], axis=1, ignore_index=True, join='inner')

ignore_index=True : 인덱스 재배열은 정렬의 한 옵션이지만 지원하지 않는 함수가 있기 때문에, sort를 사용하는게 더 편함.
concat으로 merge의 역할도 가능하지만 merge가 더 많은것을 포함하고 편함.

  • APPEND
    기능이 없어질 예정으로 아래와 같이 concat 으로 변경하여 실행.
# 에러가 아닌 경고메시지로, 이를 무시하고 싶다면 아래와 같은 코드를 입력해주시면 됩니다.
# import warnings
# warnings.filterwarnings('ignore')
# 단순 결합, 없는 건 NaN으로 처리되고 결합
# df2 가 df 의 아래로 붙음
# df.append(df2)
# pd.concat([df, df2])
  • Pivot Table 구현하기
# age 라는 축을 기준으로 카테고리별 고객id 카운트 
pd.pivot_table(df2, index='Age', columns='Category', values='Customer ID', aggfunc='count')

-인덱스 즉 왼쪽의 열에 age가 들어가고, 카테고리를 각 컬럼으로 변경하고, 그 안에 커스텀아이디를 값으로 넣을건데 count의 형태로 넣을꺼야.

# age, Category 라는 축을 기준으로 성별 Previous Purchases 최소, 최대값 구하기 
pd.pivot_table(df2, index=['Age','Category'],columns='Gender', values='Previous Purchases', aggfunc=['min','max']).plot(kind='bar')

*중앙값도 같이 확인해서 분포도 확인해보는것이 좋다.

# 성별을 축으로 하고, 사이즈, 나이별 고객id 고유하게 카운트 
pd.pivot_table(df2, index=['Gender'],columns=['Size','Age'], values='Customer ID', aggfunc='nunique')

  • 그 외 유용한 메서드 소개
    -lambda
#lambda 함수를 이용한 홀수 출력하기 
mylist = [1, 2, 3, 4, 5]
mylist2 = list(filter(lambda x: x % 2 == 1, mylist))
mylist2

[1, 3, 5]

#lambda 함수를 이용한 정렬
mylist = ['apple', 'banana', 'cherrycherry','kiwi','orange','watermellon']
mylist2 = sorted(mylist, key=lambda x: len(x))
mylist2

['kiwi', 'apple', 'banana', 'orange', 'watermellon', 'cherrycherry']

-split

# 예시 문자열 선언 
s = "aa.bb.cc.dd.ee.ff.gg"

# '.' 구분자를 기준으로 데이터를 나눔 
# 아래 두 코드 결과 동일 
s.split('.')
s.split(sep='.')

['aa', 'bb', 'cc', 'dd', 'ee', 'ff', 'gg']

# split 이해하기 - 단일 문자열
s.split('.')[6]

'gg'

# split 이해하기 - Series 
# [] 슬라이싱 기능
df2['x']

df2['Location'][1]

'Maine'

# split 이해하기 - Series 
df2['x'][0].split('.')[6]

'gg'

# split 이해하기 - Series 
len(df2['x'][0].split('.'))

7

# '.' 구분자를 기준으로 데이터를 나누고 컬럼으로 받음 
# lambda 함수와 결합하여 사용하는 경우 
df2['x']="aa.bb.cc.dd.ee.ff.gg"
df2

# 7번 반복, a 를 컬럼 구분자로 받아주고, format 함수를 통해 a0, a1, a2 ... 로 표기
# lambda 함수를 통해 '.' 로 구분. 단, len(x.split('.') 즉 7 보다 i 가 작을 때 수행
for i in range(7):
    df2["c{}".format(i)] = df2['x'].apply(lambda x: x.split('.')[i] if len(x.split('.'))>i else None)

  • rrule
# 라이브러리 불러오기
from datetime import datetime
from dateutil.rrule import rrule, DAILY

# 시작 날짜, 종료날짜
start_date = datetime(2023, 2, 1)
end_date = datetime(2023, 3, 1)

# 2023-02-01 부터 2023-03-01 까지 strf 사용하여 원하는 데이터 형식으로 출력.
daily_rule = rrule(DAILY, dtstart=datetime(2023, 2, 1), until=datetime(2023, 3, 1))

# 생성된 날짜 출력
for date in daily_rule:
    print(date.strftime('%Y-%m-%d'))

-데이터프레임에서 특정 날짜기간에 해당하는 데이터만 슬라이싱 하기

# 2023-02-01 부터 2023-03-01 까지 strf 사용하여 원하는 데이터 형식으로 출력.
weekly_rule = rrule(DAILY, dtstart=start_date, until=end_date)
# 빈 리스트 생성 후 날짜를 담아주기
a=[]
for date in weekly_rule:
    a.append(date.strftime('%Y-%m-%d'))

# df3 에 있는 날짜 데이터는 string 
# string -> datetimd -> string 의 형태로 변환
# 위에서 받은 리스트에 해당하는 데이터만 필터링하기 위함 
df3['Time stamp2'] = pd.to_datetime(df3['Time stamp']).dt.strftime('%Y-%m-%d')

mask =(df3['Time stamp2'].isin(a))

df3[mask]

인사이트

실습을 직접해보면서 강의를 들으니 이전보다는 이해가 쉬웠지만, 반복이 필요할것 같고, 꼭 필요한 부분은 merge와 lamda&split결합형태에 대해서는 확실히 알고 넘어가는것이 좋을 것 같다.

profile
Be DBA

0개의 댓글