이번 주에는 Python 기초 문법 파트를 끝내고, 데이터 분석 및 시각화 라이브러리인 Numpy, Pandas, Matplotlib, Seaborn을 배웠다.
데이터 분석 및 시각화 라이브러리는 모든 원리를 이해하거나 외우려고 하기보다는, 각 라이브러리별로 제공하는 기능을 파악해둔 뒤 필요에 따라 사용하는 게 좋을 것 같았다. 실습 몇 차례 하면 좀더 빠르게 감을 잡을 수 있을 것 같다.
이번 주 도중에 학원 같은 반에 코로나 확진자가 나오면서 비대면 수업이 시작되었다. 1차적으로 비대면 기간이 정해진 뒤 그 도중에 앞으로의 대책을 논의하겠다고 하는데, 매일매일 통근하는 일상이 익숙해져 가다가 하루아침에 뒤집히니까 타격이 꽤 크다.
부디 이전의 일상이 돌아왔으면 좋겠는데, 지켜보는 수밖에 없다.
Python 클래스 & 객체, 객체변수 & 클래스 변수, 생성자 __init__
& self
활용, 매직 메소드, StaticMethod / ClassMethod, 상속, 은닉성
# 신짱구를 만들고, age라는 객체변수를 만드시고, show_age라는 메소드를 통해 나이를 출력할 수 있도록 해주세요.
# 쌤 최최종예시 & 설명
class Person:
age = 7 # 클래스변수
def __init__(self): # __init__에서 정한 애들은 처음에 인스턴스를 만들 때 물려줍니다
normal_taste = {'좋아하는색': '빨강', '음식':['김치', '요거트']}
age = 7
self.name = '사람이름'
self.nation = 'Korea' # 인스턴스 변수
self.wearing_cloths = True
print('인스턴스를 만드셨군요')
def say_hi(): # 클래스 메소드 - self가 안 들어간 때 : 클래스에서는 호출됨, 객체에서는 호출 안 됨
print('안녕하세요.')
def say_hi_instance(self): # 인스턴스 메소드 - self가 들어간 때 : 클래스에서는 호출 안 됨, 객체에서는 호출됨
print(f'안녕하세요. {self.name}입니다.') # self.name -> 객체변수
def show_age(self): # 인스턴스를 찍어낼 때 물려줄 게 있어서 self를 사용한다면 파라메터의 맨 앞에 위치시켜야 합니다
print(f'{self.name}의 나이는 {Person.age}입니다. ') # Person.age - 클래스 변수, self.name - 인스턴스 변수
class Person:
nation = 'Korea'
def __init__(self, name, age):
self.name = name
self.age = age
def method(self, a, b):
return a+b
@staticmethod # 고정된, 한번 만들어놓으면 자식 클래스에서도 같은 방식으로 동작
def method1():
return Person.nation
@classmethod # 해당 클래스에 맞게 메서드가 다른 지점을 참조하여 동작
def method2(cls):
print('cls', cls)
return cls.nation
객체변수: 클래스에서 만들어 놓은 객체별 속성 및 기능
클래스변수: 클래스에서 미리 채워놓은 객체별 속성 및 기능
둘을 분리해서 사용할 것.
함수도 기본 취급은 클래스임.
상속, 은닉, StaticMethod/ClassMethod 다시 보기
NumPy 시작 - ndarray 만들기, 메소드, 브로드캐스팅
2차원 배열, 행벡터/열벡터, 인덱싱 & 슬라이싱
import numpy as np
test = np.array([15, 20, 25, 30])
type(test)
---> numpy.ndarray
# np.arange - ndarray 수열을 만들어주는 메소드
test1 = np.arange(15, 31, 5) # 시작점, 끝+1, 스텝, r이 1개!!
test1
---> array([15, 20, 25, 30])
# 리스트 여러개 겹친 ndarray
test = [1, 2, 4, 5, 6]
test2 = np.array([test, test, test])
test2
---> array([[1, 2, 4, 5, 6],
[1, 2, 4, 5, 6],
[1, 2, 4, 5, 6]])
a = np.array([[1, 2, 3], [4, 5, 6]], 'int8') # (들어갈 자료, 들어갈 데이터 타입)
test2 = array([[1, 2, 4, 5, 6],
[1, 2, 4, 5, 6],
[1, 2, 4, 5, 6]])
test2.dtype
---> dtype('int64')
test2.strides # 8byte * 5가 리스트 한조각당 걸리네..?
---> (40, 8)
a = 1 # 스칼라
b = np.array([1, 2, 3, 4]) # 행벡터: 1차원 배열
d = np.array([[1], [2], [3], [4]]) # 열벡터: 원소 1개짜리 1차원 배열 여러개
c = np.array([[1, 2, 3, 4], [5, 6, 7, 8]]) # 매트릭스
c = np.array([[1, 2, 3], [4, 5, 6]])
c.reshape(3, 2) # 이렇게 모양을 바꿀수가 있네?
---> array([[1, 2],
[3, 4],
[5, 6]])
a = np.insert(a, 1, 15) # insert(배열, 위치, 삽입할 값)
a = np.delete(a, -1) # np.delete(자료형, 삭제할 인덱스값)
np.random.rand(10) # 0~1 사이에서 무작위 실수 10개
np.random.randint(0, 11, 10) # 0~10 사이 정수 랜덤 10개 뽑아내기 (복원추출)
NumPy 메소드 - concatenate 등
Pandas 배우기. DataFrame 자료형 이해, 메소드 알아두기
a1[:, 1:, 1] # 슬라이싱, 슬라이싱, 인덱싱
---> array([[14, 17],
[24, 27],
[34, 37]])
b.transpose() # 전치행렬: 행벡터 => 열벡터 (거꾸로!)
import numpy as np
import pandas as pd # numpy, pandas는 다 같이 써야 함.
data = { 'Name': ['S1', 'S2', 'S3'],
'Age': [25, 28, 22],
'Score': [95, 85, 75]}
data = pd.DataFrame(data)
type(data)
---> pandas.core.frame.DataFrame # 표 형태: DataFrame
type(data['Name'])
---> pandas.core.series.Series # 한 줄 데이터: series
series = pd.Series([10, 20, 30, 50])
---> 0 10
1 20
2 30
3 50
dtype: int64
df_copy1 = data
df_copy2 = data.copy() # pd.copy(data)로 작용함. 파이썬에서는 copy()가 shallow copy 메소드였지만, 데이터프레임은 deepcopy()를 기본 복사방법으로 처리.
Pandas 메소드: tail, head, info, describe, duplicated, nunique, isnull, to_csv 등 파일 만들기 메소드, groupby, melt, pivot 등
# 데이터프레임에 컬럼이 존재하지 않으면 새로 생성
df['지역'] = '서울'
# '지역' 컬럼 드랍
df2.drop(['지역'], axis=1, inplace=True) # axis=0은 행을 의미하니까요...?
# inplace=True 로 동일변수에 재할당 가능.
# df 함수 쓰기
def add_one(x):
return x+1
df['테스트점수'] = df['테스트점수'].apply(add_one) # 아예 이래주면 되는 거였네.... apply 잘해주는게 관건이었다
df
# re 활용
df.filter(regex='지') # 컬럼명에서 원하는 값 찾기
df[df['이름'].isin(['훈이'])] # isin은 리스트를 파라메터로 가짐. 리스트 내 값 중 하나라도 존재하면 True, 아니라면 False
# '훈이'는 되지만 '훈'은 안됨.
df1.filter(regex='[a]') # [] 붙여주기. 이 함수는 대소문자를 구별함.
# 90점 이상인 사람 중 A나 B반 사람만 검색 (isin)
df1.loc[(df1['Score'] >= 90) & (df1['Class'].isin(['A', 'B']))]
# 해답: 리스트, 시리즈 등 형태를 앞뒤 동일하게 맞추고 리스트로 씌우는 것.
df1[df1['Name'].str.startswith('짱')] # str.startswith: 시작하는 문자열 찾기
df1[df1['Name'].str.endswith('구')] # str.endswith: 끝내는 문자열 찾기
df1[df1['Name'].str.contains('둥')] # str.contains: 위치 무관하게 존재하는 문자열 찾기
# groupby
df.groupby('Class').count()
df.groupby("묶음의 기준이 되는 컬럼명")["적용받는 컬럼"].적용받는 연산()
df1.pivot(index='product', columns='store', values='price')
# concatenate - 배열과 배열 합치기
df_vertical = pd.concat([df1, df1]) # axis=0이 기본
df12.drop(df12[df12['Name'].isin(['유리'])].index)
Pandas 복습
matplotlib - 기본 사용법, 그리려는 그래프 종류에 따른 명령어 사용법
seaborn - 기본 사용법, 그리려는 그래프 종류에 따른 명령어 사용법
# matplotlib
plt.plot(np.random.randn(30).cumsum(), linestyle='--', marker='^')
plt.plot(np.random.randn(30).cumsum(), linestyle='--', marker='x')
plt.plot(np.random.randn(30).cumsum(), linestyle='--') # 색 자동변환
# 히스토그램 만들기
import matplotlib.pyplot as plt
import numpy as np
# Use numpy to generate a bunch of random data in a bell curve around 5.
n = 5 + np.random.randn(1000)
m = [m for m in range(len(n))]
plt.bar(m, n)
plt.title("Raw Data")
plt.show()
plt.hist(n, bins=20) # bins 히스토그램의 구간
plt.title("Histogram")
plt.show()
plt.hist(n, cumulative=True, bins=20) # cumulative - 누적그래프
plt.title("Cumulative Histogram")
plt.show()
# seaborn
sns.set_theme(style="ticks")
plt.figure(figsize=(20, 20)) # 그래프 크기
sns.lmplot(x="x", y="y", col="dataset", hue="dataset", data=df, # hue : 컬럼명 기준으로 데이터 색깔 구분해줌
col_wrap=2, ci=None, palette="muted", height=4, # col_wrap : 한 줄에 몇개의 그래프를 그릴지, palette: 색상 컨셉 지정
scatter_kws={"s": 100, "alpha": 0.7}); # scatter_kws : 점의 색깔, 투명도 등 속성 지정
plt.show()
plt.savefig('lm.png') # 파일로 저장