본문 바로가기

멀티캠퍼스 프로젝트형 AI 서비스 개발 5회차/ML

3/17 목

728x90

목요일!

 

오늘은 외부 resource를 이용해서 DataFrame을 생성하는 것을 배운다.

 

첫 번째 방법은 CSV 파일 사용,

두 번째는 MySQL 안에 DB로부터 SQL 이용해 DataFrame을 생성 - SQL 직접 or ORM 방식(Django)

 

Jupyter Notebook과 MySQL 연동시키기 위해 Anaconda Prompt로 외부 모듈 설치

conda activate machine
conda install pymysql

 

1. MySQL에 새로운 schema 생성 후 메뉴에서 Open SQL Script로 DB 열기

새로운 Query Tab 열리면 번개 눌러주고, 안에 있는 DB 확인

create database lecture_0317;
use lecture_0317;

select * from lecture_0317.book;

 

2. Jupyter Notebook에 필요한 모듈들 불러오고 MySQL 연결하기

import pymysql
import numpy as np
import pandas as pd

con = pymysql.connect(host='localhost', # DB 연결. 연결이 성공하면 연결객체를 얻음
                     user='root',
                     password='1234',
                     db='lecture_0317',
                     charset='utf8')
# print(con) # <pymysql.connections.Connection object at 0x00000277BA7AEC10>. 연결 성공!

sql = "SELECT bisbn, btitle, bauthor, bprice FROM book WHERE btitle LIKE '%java%'"

df = pd.read_sql(sql, con)
display(df)

 

3. 현재 DataFrame의 내용을 JSON 파일로 저장. with 구문을 이용하고 폴더는 미리 생성되어 있어야 함

파일을 열어서 안의 내용을 저장하고 닫아주기(close. 안 하면 저장 안 됨) 위해 with 구문을 사용함

with 구문 사용하면 close 하는 부분을 코드로 작성하지 않아도 됨

import pymysql
import numpy as np
import pandas as pd

con = pymysql.connect(host='localhost',
                     user='root',
                     password='1234',
                     db='lecture_0317',
                     charset='utf8')
# print(con)

sql = "SELECT bisbn, btitle, bauthor, bprice FROM book WHERE btitle LIKE '%java%'"

df = pd.read_sql(sql, con)
display(df)

# jupyter_home/data/json 안에 해당 파일이 있으면 열고, 없으면 생성. 'w'는 쓰기 모드
with open('./data/json/books.json', 'w', encoding='utf-8') as file:
    df.to_json(file, force_ascii=False) # force_ascii는 문자셋에 대한 옵션

해당 경로에 생성된 JSON 파일 내용을 웹에서 JSON formatter으로 보기 좋게 JSON 파일 열어보기

 

4. JSON을 DataFrame으로 만들기

import numpy as np
import pandas as pd
import json # 내장 모듈

with open('./data/json/books.json', 'r', encoding='utf-8') as file: # 'r'는 읽기 모드
    dict_books = json.load(file)                                    # JSON으로 읽기

print(dict_books)

df = pd.DataFrame.from_dict(dict_books)
display(df)

 

5. Open API 이용해서 DataFrame을 생성해보기

연습문제

import numpy as np
import pandas as pd
import urllib # Open API 호출하기 위해서 필요한 내장 모듈
import json

# key = 67c59b547b84d9de7658ebb921457f4c
url = 'http://kobis.or.kr/kobisopenapi/webservice/rest/boxoffice/searchDailyBoxOfficeList.json'
query_string = '?key=67c59b547b84d9de7658ebb921457f4c&targetDt=20220301'
movie_url = url + query_string

load_page = urllib.request.urlopen(movie_url) # <http.client.HTTPResponse object at 0x000001DA3E642C40>
# Open API 연동이 성공하면 request에 대한 response 객체가 생성됨
# print(load_page)

my_dict = json.loads(load_page.read()) # Open API 호출 결과를 dictionary로 얻어냄
print(my_dict)

# my_dict를 잘 분해해서 DataFrame으로 만들어야 함

 

6. 직접 DataFrame 작성하기

import numpy as np
import pandas as pd

my_dict = {'이름': ['홍길동', '아이유', '김연아', '신사임당'],
           '학과': ['철학', '수학', '컴퓨터', '국어국문'],
           '학년': [1, 3, 2, 4],
           '학점': [1.4, 2.7, 3.5, 2.9]}

df = pd.DataFrame(my_dict)
display(df)

df = pd.DataFrame(my_dict, columns=['학과', '이름', '학점', '학년'],
                 index=['one', 'two', 'three', 'four'])
display(df)

 

7. indexing과 slicing

import numpy as np
import pandas as pd

my_dict = {'이름': ['홍길동', '아이유', '김연아', '신사임당'],
           '학과': ['철학', '수학', '컴퓨터', '국어국문'],
           '학년': [1, 3, 2, 4],
           '학점': [1.4, 2.7, 3.5, 2.9]}

df = pd.DataFrame(my_dict, columns=['학과', '이름', '학점', '학년'],
                 index=['one', 'two', 'three', 'four'])
display(df)

# print(df['이름'])         # Series가 출력됨

my_name = df['이름']
my_name['one'] = '강감찬' # indexing을 하면 view가 생성되면서 원본(DataFrame)도 바뀜
print(my_name)
display(df)

Fancy indexing

import numpy as np
import pandas as pd

my_dict = {'이름': ['홍길동', '아이유', '김연아', '신사임당'],
           '학과': ['철학', '수학', '컴퓨터', '국어국문'],
           '학년': [1, 3, 2, 4],
           '학점': [1.4, 2.7, 3.5, 2.9]}

df = pd.DataFrame(my_dict, columns=['학과', '이름', '학점', '학년'],
                 index=['one', 'two', 'three', 'four'])
display(df)

# 비연속적인 두 개 이상의 column을 추출할 때는 Fancy indexing. Series가 아닌 DataFrame으로 나옮
display(df[['이름', '학년']])

 

특정 cloumn에 대한 값을 변경

import numpy as np
import pandas as pd

my_dict = {'이름': ['홍길동', '아이유', '김연아', '신사임당'],
           '학과': ['철학', '수학', '컴퓨터', '국어국문'],
           '학년': [1, 3, 2, 4],
           '학점': [1.4, 2.7, 3.5, 2.9]}

df = pd.DataFrame(my_dict, columns=['학과', '이름', '학점', '학년'],
                 index=['one', 'two', 'three', 'four'])
display(df)

df['학년'] = 1 # column은 1차원, 1은 scala(0차원)이므로 brodcasting이 일어남
display(df)
df['학년'] = [2, 3, 4, 4]
display(df)

새로운 cloumn을 추가

import numpy as np
import pandas as pd

my_dict = {'이름': ['홍길동', '아이유', '김연아', '신사임당'],
           '학과': ['철학', '수학', '컴퓨터', '국어국문'],
           '학년': [1, 3, 2, 4],
           '학점': [1.4, 2.7, 3.5, 2.9]}

df = pd.DataFrame(my_dict, columns=['학과', '이름', '학점', '학년'],
                 index=['one', 'two', 'three', 'four'])
display(df)

df['나이'] = [20, 22, 30, 25]    # 새로운 컬럼을 추가
display(df)

df['조정학점'] = df['학점'] * 1.2 # 연산을 통해 새로운 컬럼을 추가할 수 있음
display(df)

column 혹은 row를 삭제

import numpy as np
import pandas as pd

my_dict = {'이름': ['홍길동', '아이유', '김연아', '신사임당'],
           '학과': ['철학', '수학', '컴퓨터', '국어국문'],
           '학년': [1, 3, 2, 4],
           '학점': [1.4, 2.7, 3.5, 2.9]}

df = pd.DataFrame(my_dict, columns=['학과', '이름', '학점', '학년'],
                 index=['one', 'two', 'three', 'four'])
display(df)

new_df = df.drop(['학점'], axis=1, inplace=False) # drop()은 행/열을 삭제. axis=1로 열을 지울 것이라고 명시. inplace로 사본 생성
display(new_df)

 

8. row에 대한 indexing과 slicing

df[]는 column indexing 할 때만 사용! row는 slicing만 가능!

import numpy as np
import pandas as pd

my_dict = {'이름': ['홍길동', '아이유', '김연아', '신사임당'],
           '학과': ['철학', '수학', '컴퓨터', '국어국문'],
           '학년': [1, 3, 2, 4],
           '학점': [1.4, 2.7, 3.5, 2.9]}

df = pd.DataFrame(my_dict, columns=['학과', '이름', '학점', '학년'],
                 index=['one', 'two', 'three', 'four'])
display(df)

# df['이름'] # print() 안 써도 jupyter notebook은 맨 마지막 코드를 출력해줌
# print(df['이름':'학년'])               # column에 대한 scling은 Error!
# display(df[['학과', '이름', '학년']])  # column에 대한 Fancy indexing은 가능!

# print(df[0])                          # row에 대한 단일 indexing은 Error!
display(df[0:2])                       # row에 대한 slicing만 가능! DataFrame, view
# display(df[[0,2]])                    # row에 대한 Fancy indexing은 Error!

# row indexing(지정 index를 이용)
# print(df['one'])            # row에 대한 단일 지정 indexing은 Error!
display(df['one':'three'])    # row에 대한 지정 slicing만 가능!
display(df[['one', 'three']]) # row에 대한 지정 Fancy indexing은 Error!

df.loc[] 사용하면 column/row indexing 모두 가능! 단, 숫자 index 쓸 수 없고 지정 index만 사용 가능

df.iloc[] 사용하면 row 숫자 indexing 가능!

import numpy as np
import pandas as pd

my_dict = {'이름': ['홍길동', '아이유', '김연아', '신사임당'],
           '학과': ['철학', '수학', '컴퓨터', '국어국문'],
           '학년': [1, 3, 2, 4],
           '학점': [1.4, 2.7, 3.5, 2.9]}

df = pd.DataFrame(my_dict, columns=['학과', '이름', '학점', '학년'],
                 index=['one', 'two', 'three', 'four'])
display(df)

# df[]는 column indexing에만 사용! row indexing에는 df.loc[] 사용하면 column/row indexing 모두 가능! 단 숫자 indexing은 Error!
print(df.loc['one'])             # Series. 단일 indexing 가능!
# display(df.loc['one':'three'])   # row에 대한 지정 slicing 가능!
# display(df.loc[['one','three']]) # row에 대한 지정 Fancy indexing 가능!

# print(df.loc[0])                 # row에 대한 숫자 indexing은 Error!
# display(df.loc['one':-1])        # Error!
print(df.iloc[3])                # row 숫자 indexing 하려면 iloc 사용!

import numpy as np
import pandas as pd

my_dict = {'이름': ['홍길동', '아이유', '김연아', '신사임당'],
           '학과': ['철학', '수학', '컴퓨터', '국어국문'],
           '학년': [1, 3, 2, 4],
           '학점': [1.4, 2.7, 3.5, 2.9]}

df = pd.DataFrame(my_dict, columns=['학과', '이름', '학점', '학년'],
                 index=['one', 'two', 'three', 'four'])
display(df)

display(df.loc['two':'three'])                   # row에 대한 지정 slicing
display(df.loc['two':'three', '학과':'이름'])    # [행, 열] 지정 slicing
print(df.loc['two':'three', '이름'])             # Series
display(df.loc['two':'three', ['이름', '학년']]) # Fancy indexing

 

9. Boolean indexing

import numpy as np
import pandas as pd

my_dict = {'이름': ['홍길동', '아이유', '김연아', '신사임당'],
           '학과': ['철학', '수학', '컴퓨터', '국어국문'],
           '학년': [1, 3, 2, 4],
           '학점': [1.4, 2.7, 3.5, 2.9]}

df = pd.DataFrame(my_dict, columns=['학과', '이름', '학점', '학년'],
                 index=['one', 'two', 'three', 'four'])
display(df)

display(df['학점'] > 3.0) # Boolean indexing 예시 1
display(df[df['학점'] > 3.0])

df.loc[df['학점'] >= 3.0, ['학과', '이름']] # Boolean indexing 예시 2

10. 새로운 row 추가

import numpy as np
import pandas as pd

my_dict = {'이름': ['홍길동', '아이유', '김연아', '신사임당'],
           '학과': ['철학', '수학', '컴퓨터', '국어국문'],
           '학년': [1, 3, 2, 4],
           '학점': [1.4, 2.7, 3.5, 2.9]}

df = pd.DataFrame(my_dict, columns=['학과', '이름', '학점', '학년'],
                 index=['one', 'two', 'three', 'four'])
display(df)

# df.loc['five',:] = ['영어영문', '강감찬', 3.7, 1] # 새로운 row를 추가
# display(df)

df.loc['five',['학과', '이름']] = ['물리학과', '강감찬'] # 새로운 행에 학과, 이름 열의 값만 추가
display(df) # NaN은 값이 없는 결치값. Series에 따라 dtype이 결정됨. 정수 열이면 정수, 실수 열이면 실수

 

11. row 삭제

import numpy as np
import pandas as pd

my_dict = {'이름': ['홍길동', '아이유', '김연아', '신사임당'],
           '학과': ['철학', '수학', '컴퓨터', '국어국문'],
           '학년': [1, 3, 2, 4],
           '학점': [1.4, 2.7, 3.5, 2.9]}

df = pd.DataFrame(my_dict, columns=['학과', '이름', '학점', '학년'],
                 index=['one', 'two', 'three', 'four'])
display(df)

new_df = df.drop('three', axis=0, inplace=False)
display(new_df)

여기까지가 DataFrame의 column, row indexing에 대한 내용!


이제부터 DataFrame이 제공하는 함수(기능)들을 살펴보자!

 

UCI Machine Learning Repository에서 제공하는 MPG(Mile per Gallon) Data set(자동차 연비)을 이용. CSV 파일

1. DataFrame이 제공하는 함수(기능)들

# DataFrame이 제공하는 함수(기능)들
# UCI Machine Learning Repository에서 제공하는 MPG(Mile per Gallon) Data set(자동차 연비)을 이용. CSV 파일
# mpg:연비, cylinders:몇 기통인지, displacement:배기량, horsepower:출력, weight:중량,
# cceleration:가속력, year:출시연도, origin:제조국(1 USA, 2 EU, 3 Japan), name:차량이름

import numpy as np
import pandas as pd

df = pd.read_csv('./data/auto-mpg.csv', header=None) # data에 column 명이 없음을 명시

df.columns = ['mpg', 'cylinders', 'displacement', 'horsepower', 'weight', 'acceleration', 'year', 'origin', 'name']

# display(df)

display(df.head()) # head() 상위 5개(default) record 추출. 안에 인자주면 그 숫자만큼
display(df.tail()) # tail() 하위 5개 record 추출

print(df.shape)    # (398, 9). 2차원 398행 9열
print(df.info())   # info() DataFrame의 기본 정보
print(df.count())  # count() 유효한 값(NaN 제외)의 개수. 결과는 Series
print(df['origin'].value_counts()) # value_counts() Series에 대해서 unique value의 개수를 알려줌

# value_counts()에 dropna=True/False 옵션을 줘서 NaN 값을 제외할 수 있음. True는 제외/False는 포함
# print(df['origin'].value_counts(dropna=True))

print(df['origin'].unique()) # unique() Series에 대해서 중복을 제거하는 함수
print(df['year'].unique())

# isin() 안에 인자가 들어있는지 확인. Boolean mask 만들기 위해서 많이 사용
df['origin'].isin([1,2]) # 제조국이 1 USA, 2 EU인 mask
df['origin'].isin([3]) # 제조국이 3 Japan인 mask
df.loc[df['origin'].isin([3]),:] # Boolean indexing

 

2. data의 index/value를 기반으로 한 정렬

import numpy as np
import pandas as pd

np.random.seed(1) # 난수의 재현성을 확보하기 위해
df = pd.DataFrame(np.random.randint(0,10,(6,4)), # 2차원 6행 4열. 0부터 9 사이의 24개 정수형 난수
                 columns=['A', 'B', 'C', 'D'],
                 index=pd.date_range('20220101', periods=6)) # .date_range('시작일', 범주)
# display(df)
# index를 섞어보자
# np.random.shuffle(df.index) # shuffle() 원본 data의 순서를 바꿈
# DataFrame의 index는 mutable operation을 지원하지 않음 -> shuffle 못 씀

random_index = np.random.permutation(df.index) # np.random.permutation() 사본을 만들어 섞음. index에 따라 data도 같이 움직임
# print(random_index)
# 이렇게 변경된 index로 DataFrame을 재설정해야 함
df2 = df.reindex(index=random_index,
                 columns=['B', 'A', 'D', 'C'])
display(df2)

# display(df2.sort_index(axis=1, ascending=True)) # column을 정렬. asc 오름차순, des 내림차순
# display(df2.sort_index(axis=0, ascending=True)) # row를 정렬

display(df2.sort_values(by='B', ascending=True))  # B 컬럼을 지정해주고 그에 대한 row를 정렬

 

1. 3/15 화 2. 3/16 수 3. 3/17 목 4. 3/18 금 5. 3/21 월
ML
환경 설정
(아나콘다, 주피터 노트북),
Pandas,
Numpy,
ndarray
ML
Numpy,
행렬곱연산,
전치행렬,
iterator,
axis,
Pandas,
Series,
DataFrame
ML
Pandas,
DataFrame,
함수들
ML
Pandas
ML

* 이해가 잘 안 되는 부분은 실제로 예제를 풀어보자!

728x90

'멀티캠퍼스 프로젝트형 AI 서비스 개발 5회차 > ML' 카테고리의 다른 글

3/22 화  (0) 2022.03.22
3/21 월  (0) 2022.03.21
3/18 금  (0) 2022.03.18
3/16 수  (0) 2022.03.16
3/15 화  (0) 2022.03.15