데이터 분석을 위한 라이브러리_1
조만간 다시 데이터 분석 keep going
NIPA-AI 온라인교육[기본교육과정] 데이터 분석을 위한 라이브러리_1
01. 파이썬의 여러가지 모듈과 패키지
01. 모듈
모듈의 필요성
코드의 길이가 길어지는 상황에서 모든 함수, 변수를 구현하는 것은 불가능
→ 누군가 만들어 놓은 함수, 변수 등을 활용해보자!
모듈
특정 목적을 가진 함수, 자료의 모임
라면 레시피 (모듈) → 스프의 양(5), 넣어야 하는 물의 양(500), 쿠지라이식 라면 끓이기(ku_ramen() 함수), 해장라면 끓이기(sok_ramen() 함수)
02. 모듈 사용하기
모듈 불러오기
import(불러오다) 키워드를 이용해서 모듈 사용
import random
# random 모듈 불러오기
모듈 사용법 확인하기
모듈 속 사용하려는 함수/변수(변할 수 있는 수)의 사용법 확인
<ex>
random.randrange(start, stop, step)
Return a randomly selected element from range(start, stop, step)
random.randrange(start, stop) random은 모듈, randrange는 함수
range(start, stop)중의 한 원소를 가져옴
모듈 사용하기
.(dot)을 쓴 후에 모듈 속 함수, 변수 사용
import random
print(random.randrange(0,2))
#0이상 2미만 수 중 임의로 출력
모듈 만들기
우리가 원하는 내용이 담긴 모듈 제작 가능
.py(파이썬 파일)로 만들 수 있다
- py파일을 생성 후, 함수와 변수를 만든다.
#cal.py
def plus(a,b):
c = a + b
return c
- 다른 파일에서 만들어 둔 py 파일을 불러온다
#main.py
import cal
- 불러온 모듈 속 함수, 변수를 활용한다
#main.py
import cal
print(cal.plus(3, 4))
#7
03. 패키지
모듈을 폴더(Directory)로 구분하여 관리하는 것
왜 패키지가 필요해?
모듈을 편리하게 관리하기 위해서!!
예를 들어, user라는 폴더에 cal이라는 모듈의 plus라는 함수를 쓰려면?
방법 1
import를 이용해서 폴더를 불러온 후, 함수 실행
import user.cal #user폴더의 cal모듈
print(cal.plus(3, 4))
방법2
from-import 사용 (from 모듈 import 함수)
함수/변수 사용시 .를 써주지 않아도 된다
from user.cal import plus
print(plus(3, 4))
#cal.plus()라고 적어주지 않아도 된다!
방법1, 2 의 예시
from random import randrange
import math
var1 = randrange(1,9)
var2 = math.log(5184, 72)
print(var1, var2)
웹페이지 정보를 가져올 수 있는 urllib 패키지
urlib.request.urlopen 함수는 해당 url의 html 파일을 가져옴
from urllib.request import urlopen
webpage = urlopen("<https://en.wikipedia.org/wiki/Lorem_ipsum").read().decode("utf-8>")
print(webpage)
- urlopen(): 이 함수에 url을 넣으면 해당 url에 접근한 결과를 얻을 수 있음
- read(): 결과를 해독하여 문자열로 반환함
- decode(): 문자열을 특정 인코딩 방식으로 해독함(유니코드, 아스키코드)
02. 데이터 핸들링을 위한 라이브러리 Numpy
01. Numpy란?
Numerical Python(수치적 파이썬)
파이썬에서 대규모 다차원 배열(많은 2차원 이상의 데이터나열)을 다룰 수 있게 도와주는 라이브러리
대표적인 라이브러리는 pandas, Numpy, Metplotilb가 있음
왜 Numpy를 사용하는가?
데이터의 대부분은 숫자 배열로 볼 수 있다
ex) 이미지 픽셀, 소리의 사운드 데이터 등
반복문 없이 배열 처리 가능!
파이썬 리스트에 비해, 빠른 연산을 지원하고 메모리를 효율적으로 사용할 수 있음!
Numpy 사용하기
list 배열 생성 및 출력 형태 확인
list_arr = list(range(5)) #0,1,2,3,4
print(list_arr) #[0,1,2,3,4] -> 콤마(,)로 구분
print(type(list_arr)) # <class 'list'>
배열 생성하기
numpy 배열 생성 및 출력 형태 확인
ndarray → n차원의 배열(n-dimensional array)을 의미함
import numpy as np #import 이용하여 numpy 불러오기
np_arr = np.array(range(5))
print(np_arr) #[0 1 2 3 4] -> 공백으로 구분
print(type(np_arr)) #<class 'numpy.ndarray'>
콤마로 구분된 값 → 리스트(1차원), 공백으로 구분된 값→ 배열
02. 배열의 기초
배열의 데이터 타입 dtype(datatype)
Numpy 배열은 파이썬 리스트와 달리 같은 데이터 타입만 저장 가능함
(파이썬 리스트는 정수형, 실수형, bool, string 과 같은 다양한 데이터를 넣을 수 있음
그러나 Numpy는 여러가지 데이터를 쓸 수 없음! 단일 데이터!)
arr = np.array([0, 1, 2, 3, 4], dtype=float)
print(arr) #[0. 1. 2. 3. 4] 실수의 형태로 나타나게됨
print(arr.dtype) #'float64'
print(arr.astype(int)) #[0 1 2 3 4] 다른 데이터 타입으로 바꾸는 astype
배열의 속성
ndarray의 차원 관련 속성:ndim(ndimensional) & shape
#1차원 배열
list = [0, 1, 2, 3]
arr = np.array(list)
print(arr.ndim) #1
print(arr.shape) #(4,)
#2차원 배열
list = [[0, 1, 2],[3, 4, 5]]
arr = np.array(list)
print(arr.ndim) #2
print(arr.shape) #(2,3) 2개의 행이 3개의 열!
ndarray의 크기속성과 shape조절
#크기속성
arr = np.array([0, 1, 2, 3, 4, 5])
print("arr.shape:{}".format(arr.shape)) #arr.shape:(6,)
print("배열 요소의 수:{}".format(arr.size)) #배열 요소의 수:6
print("배열의 길이:{}".format(len(arr))) #배열의 길이:1
arr.shape = 3, 2 #shape 바꾸기
print("arr.shape:{}".format(arr.shape)) #arr.shape:(3,2)
print("배열 요소의 수:{}".format(arr.size)) #배열 요소의 수:6
print("배열의 길이:{}".format(len(arr))) #배열의 길이:3
03. Indexing & Slicing
찾고 잘라내기
- 인덱싱
- 슬라이싱
Indexing: 인덱스로 값을 찾아냄
x = np.arange(7)
print(x) # [0 1 2 3 4 5 6]
print(x[3]) # 3
print(x[7]) #IndexError: index 7 is out of bounds
x[0] = 10
print(x) #[10 1 2 3 4 5 6]
x = np.arrange(1, 13, 1)
x.shape = 3, 4
print(x)
# [[1 2 3 4]
# [5 6 7 8]
# [9 10 11 12]]
print(x[2,3]) #12(세로로 2(1 5 9)번째 가로로 3(9 10 11 12)번째)
Slicing: 인덱스의 값으로 배열의 일부분을 가져옴
x = np.arrange(7)
print(x) # [0 1 2 3 4 5 6]
print(x[1:4])#[1 2 3]
print(x[1:]) #[1 2 3 4 5 6]
print(x[:4]) #[0 1 2 3]
print(x[::2]) #[0 2 4 6] (:)처음 부터 (:)끝까지 '2'의 간격!
x = np.arrange(1, 13, 1)
x.shape = 3, 4
print(x)
#[[1 2 3 4]
# [5 6 7 8]
# [9 10 11 12]
print(x[1:2, :2:3]) #[[5]] 세로 1부터 2전까지 ->1행만 가능, 가로는 (:)처음부터 2전까지 3간격 -> 5만 가능
print(x[1:,:2])
#[[5 6]
# [9 10] 세로는 1부터 끝까지, 가로는 앞에서부터 2직전까지
Boolean indexing: 배열의 각 요소의 선택 여부를 Boolean mask를 이용하여 지정하는 방식
- 조건에 맞는 데이터를 가져온다
- 참/거짓 여부를 알려준다
x = np.arrange(7)
print(x) # [0 1 2 3 4 5 6]
print(x<3) # [True True True False False False False]
print(x>7) #[False False False False False False False]
#Boolean mask의 True 요소에 해당하는 index만을 조회
print(x[x<3]) #[0 1 2]
print(x[x%2 ==0]) #[0 2 4 6]
Fancy indexing: 배열의 각 요소 선택을 index배열을 전달하여 지정하는 방식
찾고 싶은 자리 = 인덱스에 어떤 값이 있는지?
x = np.arrange(7)
print(x) #[0 1 2 3 4 5 6]
print(x[[1, 3, 5]]) #[1 3 5]
x = np.arrange(1, 13, 1).reshape(3, 4) #1부터 12까지 1간격으로 숫자 만들어서 (3, 4)로 모양 만들기
print(x)
#[[1 2 3 4]
# [5 6 7 8]
# [9 10 11 12]]
print(x[[0, 2]]) #0번쨰 행과 2번째 행
#[[1 2 3 4]
# [9 10 11 12]]
원하는 요소를 지정하기 위해 Indexing과 Slicing을 적절히 조합하여 사용 가능!
x = np.arange(1, 13, 1).reshape(3, 4)
print(x)
# [[1 2 3 4]
# [5 6 7 8]
# [9 10 11 12]]
print(x[1:2, 2]) #[7]
print(x[[0,2], 2) #[3 11] 세로는 0과2 인덱스, 가로는 2
print(x[[0,2], :2) #세로는 0과2, 가로는 처음부터 2까지 자르기
#[[1 2]
# [9 10]
03. 데이터 조작 및 분석을 위한 Pandas 기본
01. Series 데이터
Pandas
- 파이썬 라이브러리, 구조화된 데이터를 효과적으로 처리하고 저장
- Array계산에 특화된 Numpy를 기반으로 설계
Series
Numpy의 array가 보강된 형태, Data와 Index를 가지고 있음
Series는 값(values)을 ndarray형태로 갖고 있음
import pandas as pd
data = pd.Series([1, 2, 3, 4])
print(data)
# 0 1
# 1 2
# 2 3
# 3 4
# dtype: int64
#Index 0, 1, 2, 3
#Value(Data) 1, 2, 3, 4
#dtype:int64
print(type(data))
#<class 'pandas.core.series.Series'> 시리즈
print(data.values)
#[1 2 3 4]
print(type(data.values))
#<class 'numpy.ndarray'> 배열
dtype 인자로 데이터 타입을 지정할 수 있음
in → float로 지정, 예시
data.pd.Series([1, 2, 3, 4], dtype = "float")
print(data.dtype) #float64
인덱스를 지정할 수 있고 인덱스로 접근 가능
data = pd.Series([1, 2, 3, 4], index = ['a', 'b', 'c', 'd'])
data['c'] = 5 #인덱스로 접근하여 요소 변경 가능
02. 데이터프레임
DataFrame
여러개의 Sereis가 모여서 행과 열을 이룬 데이터
gdp_dict = {
'china' : 5
'japan' : 4
'korea' : 3
'usa' : 2
}
gdp.pd.Sereis(gdp_dict)
country = pd.DataFrame({
'gdp':gdp,
'population' : population
})
Dictionary를 활용하여 DataFrame 생성 가능
data = {
'country' : ['china', 'japan', 'korea', 'usa'],
'gdp' : [5, 4, 3, 2]
'polupation' : [10, 9, 8, 7]
}
country = pd.DataFrame(data)
country = country.set_index('country')
중간정리!
- 딕셔너리 data = {key: value}
- 시리즈(딕셔너리에서 만들 수 있음!) series([1, 2, 3, 4])
- 데이터프레임(시리즈에서는 데이터 프레임을 만들 수 있음) 앞에는 인덱스 뒤에는 시리즈 데이터!
- 딕셔너리에서 바로 데이터프레임도 만들 수 있음!
DataFrame 속성 확인
print(country.shape) #(4,2)
print(country.size) #8 전체의 개수, 4*2 = 8
print(country.ndim) #2 2차원
print(country.values)
#[[5 10]
# [4 9]
# [3 8]
# [2 8]
DataFrame-index, columns 이름 지정
country.index.name = "Country" #인덱스에 이름 지정
country.columns.name = "Info" #컬럼에 이름 지정
print(country.index)
#Index(['china', 'japan', 'korea','usa'], dtype = 'object', name = 'Country')
print(country.colums)
#Index(['gdp', 'population'], dtype='object', name="Info")
DataFrame - 저장&로드
데이터프레임 저장 및 불러오기
#저장
country.to_csv("./country.csv")
country.to_excel("country.xlsx")
#불러오기
country=pd.read_csv("./country.csv")
country=pd.read_excel("country.xlsx")
데이터 선택 및 변경하기
데이터 선택 - Indexing/Slicing
.loc: 명시적인 인덱스를 참조하는 인덱싱/슬라이싱
(iloc : 암묵적인 인덱스)
country.loc['china'] #인덱싱/ 차이나의 gdp와 population만 나오게됨 -> 명시적
country.loc['japan':'korea', :'population'] #슬라이싱
#앞은 인덱스, 뒤는 컬럼 japan, korea를 첫 컬럼부터 population까지 슬라이싱
.iloc: 파이썬 스타일의 정수 인덱스 인덱싱/슬라이싱 → 암묵적인 순서가 있고, 그에 따라 값 추출
country.iloc[0] #인덱싱/ 0번째 인덱스(china) 불러오기
country.iloc[1:3, :2] #슬라이싱/ 인덱스 1부터 2만큼만 불러오고, 컬럼 0부터 1까지 불러와라
데이터 선택 - 컬럼 선택
컬럼명 활용하여 DataFrame에서 데이터 선택 가능
country #표라고 가정
country['gdp'] #Series
country[['gdp']] #데이터 프레임
Name:gdp, dtype: int64
데이터 선택 - 조건 활용
Masking 연산이나 query 함수를 활용하여 조건에 맞는 DataFrame 행 추출 가능
country[country['population'] < 10000] #masking연산 활용
country.query("population > 100000") #query 함수 활용
데이터 선택 - 컬럼 추가
Series도 numpy array 처럼 연산자 활용 가능
gdp_per_capita = country['gdp'] / country['population']
country['gdp per capita'] = gdp_per_capita
데이터 변경 - 데이터 추가/수정
리스트로 추가 or 딕셔너리로 추가
df = pd.DataFrame(columns = ['이름', '나이', '주소']) #데이터프레임 생성
df.loc[0] = ['길동', '26', '서울'] #리스트로 데이터 추가!
df.loc[1] = {'이름':'철수', '나이':'25', '주소':'인천'} #딕셔너리로 데이터 추가
df.loc[1, '이름'] = '영희' #명시적 인덱스 활용하여 인덱스 수정. 철수->영희
#1번째 인덱스의 이름 컬럼 수정! 한다는 뜻
데이터 변경 - NaN 컬럼 추가
NaN값으로 초기화 한 새로운 컬럼 추가
df['전화번호'] = np.nan #새로운 컬럼 추가 후 초기화
#nan = not a number
df.loc[0, '전화번호'] = '01012341234' #명시적 인덱스를 활용하여 데이터 수정
데이터 변경 - 컬럼 삭제
DataFrame 에서 컬럼 삭제 후 원본 변경
df.drop('전화번호', axis = 1, inplace = True)
#axis = 1 : 열 방향 / axis = 0 : 행 방향
#inplace = True : 원본 변경 / inplace = False : 원본 변경 X
.