PYTHON 자료형 짚고넘어가기!
list : [] 대괄호로 정의, 수정가능, 순서 있음 list1 = [1, 2]
tuple: () 소괄호로 정의, 수정불가, 순서 있음 tuple1 = (1, 2)
dictionary: {} 중괄호로 정의, key와 value 값으로 나뉨, 수정가능, 순서 없음 dic = {"name": "jane", "age": 22, "grade": 'A'}
set: {} 중괄호로 정의, 순서 없음, s = {1, 2, 3}
ndarray: numpy 에서 배열을 나타내주는 자료형
series, dataframe:pandas 에서 사용하는 자료형
2회차 실습해보기
# 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
# 컬럼명이 같은 경우의 예시를 보여주기 위해 컬럼명을 임의로 변경해 줌
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
# 아래 데이터프레임에서의 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)
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가 더 많은것을 포함하고 편함.
# 에러가 아닌 경고메시지로, 이를 무시하고 싶다면 아래와 같은 코드를 입력해주시면 됩니다.
# import warnings
# warnings.filterwarnings('ignore')
# 단순 결합, 없는 건 NaN으로 처리되고 결합
# df2 가 df 의 아래로 붙음
# df.append(df2)
# pd.concat([df, df2])
# 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 함수를 이용한 홀수 출력하기
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)


# 라이브러리 불러오기
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결합형태에 대해서는 확실히 알고 넘어가는것이 좋을 것 같다.