create table dbms(
num int(10) NOT NULL AUTO_INCREMENT,
name varchar(255) NOT NULL,
vendor varchar(255) NOT NULL,
description varchar(255),
PRIMARY KEY(num)
);
INSERT INTO dbms(name, vendor, description) values('Oracle', 'Oracle', '금융과 대기업에서 많이 사용하는 가장 안정적인 데이터베이스');
INSERT INTO dbms(name, vendor, description) values('HANA DB', 'SAP', '오라클 대체용으로 사용하는 데이터베이스로 현대 자동차에서 사용');
INSERT INTO dbms(name, vendor, description) values('MySQL', 'Oracle', '현재 가장 많이 사용한다고 알려진 관계형 데이터베이스로 중소 기업이나 플랫폼 기업에서 주로 이용');
INSERT INTO dbms(name, vendor, description) values('Maria DB', 'Open Source', 'MySQL의 fork로 현재는 Kakao에서 사용하고 있습니다.');
INSERT INTO dbms(name, vendor, description) values('PostgreSQL', 'Open Source', '요즈음 많이 사용되는 데이터베이스');
.
import pandas as pd
from sqlalchemy import create_engine
import pymysql
#연결
connect = create_engine('mysql+mysqldb://root:0000@localhost/python_dataframe')
df = pd.read_sql_table('dbms', connect)
print(df)
3. 그 외의 데이터 사용
1) R의 데이터 활용
- pyreadr 이라는 패키지를 사용
- 읽는 방법
pyreadr.readr('rds 파일 경로')[None]
2) 통계 프로그램 데이터 읽어오기
- pyreadstat 패키지를 이용하면 SPSS, Stata, SAS 프로그램의 데이터를 읽을 수 있음
3) 최근 pySpark의 dataframe을 이용하는 경우가 많음
- pySpark가 가져올 수 있는 데이터의 종류가 더 많고 - pySpark에서는 SQL을 그대로 사용할 수 있기 때문에 SQL을 아는 것이 중요
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
import bs4
import os
import time
#드라이버 경로 설정
os.environ['webdriver.chrome.driver'] = 'C:\\Users\\USER\\Downloads\\chromedriver-win64\\chromedriver-win64\\chromedriver'
driver = webdriver.Chrome()
#사이트 접속
driver.get("https://www.youtube.com/results?search_query=%EB%8B%B9%EA%B7%BC%20%ED%9B%84%EA%B8%B0")
#5초 대기
time.sleep(5)
i = 0
body = driver.find_element(By.TAG_NAME, 'body')
while i < 10:
body.send_keys(Keys.PAGE_DOWN)
time.sleep(2)
i = i + 1
#html 읽어오기
html = driver.page_source
print(html)
while(True):
pass
6) 네이버 로그인
아이디 와 비밀번호를 입력했을 때 capture 가 보이는 경우는 입력을 직접하지 않고 자바스크립트를 이용하면 보이지 않을 것
from selenium import webdriver
from selenium.webdriver.common.by import By
import os
#드라이버 경로 설정
os.environ['webdriver.chrome.driver'] = 'C:\\Users\\USER\\Downloads\\chromedriver-win64\\chromedriver-win64\\chromedriver'
driver = webdriver.Chrome()
#사이트 접속
driver.get("https://nid.naver.com/nidlogin.login")
#5초간 대기
driver.implicitly_wait(5)
#userid 와 password 에 아이디와 비밀번호를 직접 입력하면 자동 로그인이 됩니다.
userid = input("아이디")
password = input("비밀번호")
driver.execute_script("document.getElementsByName('id')[0].value=\'" + userid + "\'")
driver.execute_script("document.getElementsByName('pw')[0].value=\'" + password + "\'")
driver.find_element(By.XPATH, '//*[@id="log.login"]').click()
while(True):
pass
# 정적인 웹의 데이터를 가져올 때 사용하는 패키지
import requests
html = requests.get(target_URL).text
print(html)
5) 기사 개수 가져오기
#HTML, XML 파싱에 사용하는 패키지
from bs4 import BeautifulSoup
#HTML 텍스트는 메모리에 트리 형태로 펼치기
bs = BeautifulSoup(html, 'html.parser')
#선택자는 동일한 데이터가 있을 수 있으므로 list
cnt = bs.select('div.cntPage > span')
#데이터가 1건이라서 반복문을 돌리지 않고 첫번재 데이터에서 바로 추출
'''
for x in cnt:
print(x.getText())
'''
cnt = cnt[0].getText()
#print(cnt)
cnt = int(cnt[0:-1].replace(",", ""))
print(cnt)
=> 73
6) 기사 링크 가져오기
#페이지 개수 만들기
pageno = int(cnt / 15 + 0.99)
#기사의 링크를 저장할 list
links = []
#페이지 개수 만큼 순회하면서 html을 읽어서 파싱해서 저장
for i in range(0, pageno):
#기사 링크와 제목이 나오는 페이지를 읽기
url = "https://www.donga.com/news/search?p=" + str(i*15+1) + "&query=" + keyword + "&check_news=91&more=1&sorting=1&search_date=1&v1=&v2="
html = requests.get(url).text
soup = BeautifulSoup(html, "html.parser")
linktag = bs.select('span.tit > a')
for tag in linktag:
#a 태그의 href 속성의 값을 가져오기
links.append(tag['href'])
print(links)
7) 기사 링크에 가서 기사를 읽어서 텍스트 파일에 저장
#기록할 텍스트 파일을 생성
output_file = open(string + ".txt", 'w', encoding='utf8')
for link in links:
html = requests.get(link).text
bs = BeautifulSoup(html, "html.parser")
articles = bs.select('#article_txt')
for article in articles:
#파일에 기록
output_file.write(article.getText())
output_file.close()
list · set · ndarray를 대입하면 0부터 시작하는 숫자 인덱스가 자동으로 생성
dict를 설정하면 key가 인덱스
index 옵션에 직접 인덱스 설정 가능
dtype
데이터 1개의 자료형으로 설정 -> 그 자료형으로 생성
설정 없음 -> pandas가 추론
copy: True -> 데이터 복제해서 생성 / False -> 참조를 가져와서 생성
- index와 values 속성
index 속성 호출 : 인덱스를 numpy의 ndarray로 리턴
values 속성 호출: 값들을 numpy의 ndarray로 리턴
* 딥러닝은 기본적으로 numpy의 ndarray로 수행하는데, 데이터가 pandas의 자료구조면 values 속성을 호출해서 numpy의 ndarray로 수행해야 함.
* pandas를 사용해야 하는 이유: 다양한 데이터를 불러올 수 있기 때문! pandas로 불러오고 numpy 배열로 바꿔줘야 한다.
- 하나의 데이터를 접근
Series[index]
- numpy와 동일한 형태로 연산 수행하고 numpy의 함수 사용 가능
numpy의 1차원 배열과 Series의 차이는 Index의 여부!!!
#시리즈를 생성
price = pd.Series([1000, 3000, 2000, 4000])
#시리즈를 출력 - 자동 생성된 인덱스 와 값이 출력
print(price)
#1이라는 인덱스를 가진 데이터를 조회
print(price[1])
#인덱스를 직접 설정
price.index = ["사탕", "과자", "음료수", "과일"]
print(price)
#인덱스가 사탕이라는 데이터를 조회: 1000
print(price["사탕"])
0 1000 1 3000 2 2000 3 4000 dtype: int64
3000
사탕 1000 과자 3000 음료수 2000 과일 4000 dtype: int64
1000
파이썬을 쓰는 것은 숫자가 항상 0부터 시작하고, n-1까지인데 개발자가 아닌 경우 1부터 시작하고 마지막을 포함한다. (ex.R) pandas는 데이터분석을 위한 패키지기 때문에 (1, n)으로 인식한다.
x = price["사탕":"음료수"] #사탕부터 음료수까지의 데이터의 참조를 가져온 것
#x의 데이터를 변경하면 원본인 price 의 데이터도 수정
x["사탕"] = 800
print(x)
print(price)
print("=============================================")
y = price[["사탕","음료수"]] #사탕과 음료수의 데이터를 복제해 온 것
#y의 데이터를 변경해도 원본인 price의 데이터를 변경되지 않는 것
y["사탕"] = 2000
print(y)
print(price)
사탕 800 과자 3000 음료수 2000 dtype: int64
사탕 800 과자 3000 음료수 2000 과일 4000 dtype: int64
=============================================
사탕 2000 음료수 2000 dtype: int64
사탕 800 과자 3000 음료수 2000 과일 4000 dtype: int64
x는 참조를 가져와서 쓴 것. 따라서 x의 데이터를 변경하면 원본인 price의 데이터도 변경된다.
y는 데이터를 복제함. y의 데이터를 변경해도 원본인 price의 데이터는 변경되지 않았다.
배열은 데이터의 연속적인 모임이다. array는 연속이 전제된다. 물리적으로 연속되면 array list (혹은 dense list)라고 하고, 논리적으로 연속되면 linked list라고 한다.
load_digits(): 숫자 데이터 셋 - 분류에 사용 load_iris(): 붓꽃 데이터 - 분류에 사용 load_diabetes(): 당뇨병 데이터 - 회귀에 사용 load_linnerud(): 체력 검사 데이터 - 회귀에 사용 load_wine(): 와인 품질 데이터 - 분류에 사용 load_breast_cancer(): 유방암 데이터 - 분류에 사용
#사이킷런(scikit-learn)에서 제공하는 데이터를 사용
from sklearn import datasets
#iris 데이터 읽어오기
iris = datasets.load_iris()
#print(iris)
#데이터프레임이 아니고 Bunch 클래스의 인스턴스
print(type(iris))
날짜 이름 가격 0 2017-04-10 다음 32000 1 2017-04-11 다음 34000 2 2017-04-12 다음 33000
2) csv 파일 읽기
- csv: 구분 기호로 분리된 텍스트 파일
pandas.read_csv: 기본 구분자가 쉼표(,)
pandas.read_table: 기본 구분자가 탭
- 첫번째 매개변수로 파일 경로 설정
아무런 옵션이 없으면 첫 번째 줄 데이터를 컬럼 이름으로 사용
#item.csv 파일 읽기
item = pd.read_csv('C:\\Users\\USER\\Downloads\\data\\data\\item.csv')
print(item)
print(item.info())
code manufacture name price 0 1 korea apple 1500 1 2 korea watermelon 15000 2 3 korea oriental melon 1000 3 4 philippines banana 500 4 5 korea lemon 1500 5 6 korea mango 700
nrows 속성을 이용해서 시작 위치에서 일부분의 데이터만 읽어오고 skiprows를 이용해서 읽을 수 있음
#item.csv 파일 읽기
parser = pd.read_csv('C:\\Users\\USER\\Downloads\\data\\data\\good.csv',
header=None, nrows=2, skiprows=4)
print(parser)
0 1 2 0 mango 30 1500 1 orange 4 700
반복문을 사용하면
#item.csv 파일 읽기
for i in range(0, 3):
parser = pd.read_csv('C:\\Users\\USER\\Downloads\\data\\data\\good.csv',
header=None, nrows=2, skiprows=i*2)
print(parser)
i = 0
while True:
try:
parser = pd.read_csv('C:\\Users\\USER\\Downloads\\data\\data\\good.csv',
header=None, nrows=2, skiprows=i*2)
print(parser)
i = i + 1
except:
break
chunksize를 설정해서 한 번에 읽을 데이터의 개수를 설정하고 이때 리턴되는 TextParser 객체를 순회하면서 읽을 수 있음
parser = pd.read_csv('C:\\Users\\USER\\Downloads\\data\\data\\good.csv',
header=None, chunksize=2)
for piece in parser:
print(piece)
- 탭으로 구분된 파일 읽기
ParserError: Error tokenizing data. C error: Expected 1 fields in line 326, saw 2
li = pd.read_html('https://ko.wikipedia.org/wiki/%EC%9D%B8%EA%B5%AC%EC%88%9C_%EB%82%98%EB%9D%BC_%EB%AA%A9%EB%A1%9D')
print(li[0])
인덱스를 이용해 원하는 테이블을 선택해야 함
순위 나라 인구 갱신 년도 \ 0 1 인도 1428627663 2024.0 1 2 중화인민공화국 1409670000 2024.0 2 3 미국 334914895 2023.0 3 4 인도네시아 279476346 2023.0 4 5 파키스탄 247653551 2023.0 .. ... ... ... ... 236 237 토켈라우 1893 2023.0 237 238 니우에 1681 2022.0 238 239 바티칸 시국 764 2023.0 239 240 코코스 제도 593 2021.0 240 241 핏케언 제도 47 2021.0
기타 0 공식 인구시계 UN 프로젝션[1][2][3] UN 예상치 인구가 가장 많은 국가 1 공식 인구시계 2 공식 인구시계 3 공식 인구시계 4 공식 인구시계 .. ... 236 UN 예상치 237 공식 추계치 238 바티칸 시국 인구통계 인구가 가장 적은 UN 가입국 239 공식 추계치 240 인구가 가장 적은 속령
#이미지 파일 다운로드
imageurl = "https://search.pstatic.net/common/?src=http%3A%2F%2Fblogfiles.naver.net%2FMjAyMTA1MTVfMjg1%2FMDAxNjIxMDA0ODI5MDc0.Q17_bqOFXmCDBx4kAr_UQl3vGPfvY4wNAS48RCfwja8g.UM29jj3Mra_yEHXChamjsDevclJMy13NgQRRzEbWyPAg.JPEG.gody97%2Fresized%25A3%25DFoutput%25A3%25DF1906874251.jpg&type=sc960_832"
filename ="redpanda.jpg"
try:
#다운로드
resp = requests.get(imageurl)
#파일에 저장
with open(filename, "wb") as h:
#다운로드 받은 내용을 bytes로 리턴
img = resp.content
h.write(img)
except Exception as e:
print(e)
4) json 데이터 파싱
방법
- requests를 이용해서 다운로드 받은 후 직접 파싱 - 옵션이 많을 때 좋음
- pandas.read_json을 이용해서 자동으로 파싱 - 데이터의 구조가 단순할 때 좋음
for item in movie:
print(item["title"] + ":" + item["ratingAverage"])
인포먼트:6.7 엣지 오브 다크니스:6.9 베이비 돌:6 황야의 역마차:6.3 전원 교향곡:8 아버지의 깃발:8 여덟번의감정:6 레드:8.7 영광의 탈출:6.8 크로싱:8.8 맨 인 블랙:8.9 차형사:8.4 에이지 오브 드래곤:3.9 로드 오브 워리어:7.4 [메이킹 다큐] 도둑들 영화를 만들다!:7.9 괜찮아요 수달씨:7.5 파파:9 이케맨 뱅크:6.7 다중인격소녀 ISOLA:5.7 위조지폐:6.5 카인과 아벨:6.9 돌핀 블루:8.2 더 코드:7.6 철권 블러드 벤전스:8 블루 엘리펀트 (우리말 더빙):8.8 해결사 (2010):8.3 하나오니 2: 사랑의 시작:8.5 하나오니 3: 복수의 시간:8.5 아테나 전쟁의 여신 극장판:7.7 아이스 프린세스:8.8
import xml.etree.ElementTree as et
# urllib.request를 이용해서 읽어온 데이터: res
#메모리에 펼치기
tree = et.parse(res)
#루트 찾기
xroot = tree.getroot()
#특정 태그의 데이터 가져오기
items = xroot.findall('태그')
#태그는 여러개 나올 수 있으므로 반복문 수행
for node in items:
node.find(태그).text : 태그 안의 데이터
import urllib.request
url = "https://www.chosun.com/arc/outboundfeeds/rss/category/economy/?outputType=xml"
request = urllib.request.Request(url)
response = urllib.request.urlopen(request)
#xml 파싱
import xml.etree.ElementTree as et
#메모리에 트리 형태로 펴맃기
tree = et.parse(response)
print(tree)
import numpy
import numpy as np
from numpy import * # 모듈의 모든 내용을 현재 모듈에서 사용
from numpy import ndarray # numpy 모듈 중에서 ndarray만 사용
import *을 쓰면 nupmy 써주지 않아도 사용할 수 있지만, 내장함수인지 구분이 가지 않음!
4. ndarray
- array, 배열
- list나 tuple보다 생성 방법이 다양하고 가능한 작업 많음
- id의 모임이 아니라 값의 모임
list나 tuple은 id의 모임이기 때문에 보기에는 자료형이 달라도 같은 자료형(id)으로 취급해서 생성이 가능했다.
그런데 ndarray는 동일한 자료형의 grid
ndarray를 생성할 때 다른 자료형을 대입하면 추론을 통해 하나의 자료형으로 변환해서 생성
5. 속도
import datetime
li = range(1, 100000)
#현재 시간 저장
start = datetime.datetime.now()
#모든 요소에 10 곱하기
for i in li:
i = i * 10
#현재 시간 저장
end = datetime.datetime.now()
print(start, end)
import numpy as np
ar = np.arange(1, 10000000)
#현재 시간 저장
start = datetime.datetime.now()
ar = ar * 10
#현재 시간 저장
end = datetime.datetime.now()
print(start, end)
int8는 8비트이다. int는 양수와 음수를 같이 표현한다. 양수와 음수의 모양이 각각 128가지 (-128 ~ 127)이다. 그래서 색상값 표현이 안된다. 따라서 int16을 사용해서 표현해야 함!
그런데 unit는 마찬가지로 모양이 256가지인데 음수를 표현하지 않기 떄문에 0~255 범위의 데이터를 표현하는 것이 가능하다. 메모리 효율 달성~
#데이터 타입 확인과 형변환
ar = np.array([1, "2", 3]) # 숫자 -> 문자열로 바뀜
print(ar.dtype)
ar2 = np.array([1, 2.3, 3]) # 정수 -> 실수로 바뀜
print(ar2.dtype)
#ar 배열의 자료형을 정수로 변환
ar3 = ar.astype(np.int32)
print(ar3.dtype)
🤍
<U11
float64
int32
10. 배열 차원 변환
머신러닝이나 딥러닝을 하다보면 특정한 차원의 데이터를 요구
현재 가지고 있는 데이터가 요구하는 차원과 맞지 않으면 차원을 변경해서 사용해야 함
차원 변경 함수
reshape: 차원을 튜플로 받아서 튜플에 해당하는 차원으로 변경
flatten: 무조건 1차원 배열로 변환
튜플을 대입하지 않고 -1을 대입하면 1차원으로 변경
튜플로 숫자를 설정할 때 마지막 값을 -1로 설정하면 numpy가 알아서 마지막 값 추론하고 설정
10개의 데이터가 있는 1차원 1배열 -> 2차원 배열로 변경
#0부터 19까지의 숫자를 가지고 1차원 배열 생성
ar = np.arange(20)
print(ar)
print()
#ar을 4*5짜리 2차원배열로 변환
#5 대신에 -1을 대입해도 결과는 동일
#20개의 데이터는 4행으로 만들려면 5열밖에 안됨
matrix = ar.reshape((4, -1))
print(matrix)
print()
#다차원 데이터를 1차원으로 변환
br = matrix.flatten()
print(br)
#배열에서 하나의 요소 접근
ar = np.arange(10)
matrix = ar.reshape((2, -1)) #행 2개, 열은 알아서
print(ar)
print(matrix)
#일차원 배열에 요소 접근
print(ar[0]) #첫번째 데이터
print(ar[-1]) #마지막 데이터
#이차원 배열에서 요소 접근
print(matrix[0, 2])
print(matrix[0][2])
#배열에서 범위를 이용한 접근
ar = np.arange(10)
matrix = ar.reshape((2, -1))
print(ar[1:4]) #1에서 3까지
print(ar[5:]) #5부터 마지막값까지
print(ar[:4]) #시작위치부터 3까지
print(ar[:]) #전체
#이차원 배열에서의 접근
print(matrix[1][1:3])
print(matrix[1]) #1행 전체
print(matrix[:,1]) #1열 전체
matrix = np.array([1, 2, 3])
print(matrix)
#요소의 제곱을 수행하는 람다 함수
square_lambda = lambda x : x * x
#함수를 배열의 모든 요소에 적용해서 결과를 배열로 만들기
vectorized_func = np.vectorize(square_lambda)
result = vectorized_func(matrix)
print(result)
🤍
[1 2 3]
[1 4 9]
데이터가 None 이면 0 100보다 크면 100 으로 한 결과 배열 생성 #None을 걸러내는 작업을 먼저 해야 합니다.
ar = np.array([80, 70, 80, None, 120])
def preprocessing(data) -> int:
if data == None:
return 0
elif data > 100:
return 100
else:
return data
vec_func = np.vectorize(preprocessing)
print(vec_func(ar))
#랜덤한 숫자 추출의 개념
#seed를 설정하지 않으면 실행 시간을 기준으로 seed 가 설정되므로
#실행할 때 마다 다른 숫자가 리턴
result = np.random.normal(size = 5)
print(result)
#seed를 42로 고정하면 실행할 때 마다 동일한 데이터가 리턴
np.random.seed(seed=42)
result = np.random.normal(size = 5)
print(result)
- prod: 곱 - nanprod: None 을 1로 간주하고 곱 - nansum: None을 0으로 간주하고 합
- mean: 평균 - median: 중앙값 - max: 최대 - min: 최소
- std: 표준편차 - var: 분산
- percentile: 백분위수
axis: 2차원 배열에서 행이나 열방향 과 관련된 옵션
ddof: 표준 편차 와 분산은 ddof를 1로 설정해서 비편향 표준 편차 와 분산을 계산.
자유도는 다른 데이터의 값이 결정되면 자동으로 값이 결정되는 데이터의 개수
#4행 3열짜리 배열 생성
matrix = np.arange(1, 13).reshape((4, -1))
print(matrix)
#전체 데이터의 합계
print(np.sum(matrix))
#열의 합계
print(np.sum(matrix, axis=0))
#행의 합계
print(np.sum(matrix, axis=1))
#피보나치 수열
def fibo(n: int) -> int:
if n == 1 or n == 2:
return 1
else:
return fibo(n-1) + fibo(n-2)
print(fibo(6))
def norecursion_fibo(n:int) -> int:
n1 = 1
n2 = 1
v = 1
for i in range(3, n+1):
v = n1 + n2
n2 = n1
n1 = v
return v
print(norecursion_fibo(6))
#배열 생성
ar = np.array([10, 2, 3, 4, np.nan, 32, 42])
#배열에 None 데이터가 있는지 확인
print(np.isnan(ar)) #결측치 확인
#결측치를 제외하고 가져오기
result = ar[np.logical_not(np.isnan(ar))]
print(result)
#결측치를 제외하고 가져오기 - 결측치를 제거하지 않고 수행하면 nan 이 포함됩니다.
#ar을 가지고 수행하면 np.nan 이 포함되고 result를 가지고 수행하면 np.nan이 제거
result = result[np.logical_not(result > 10)]
print(result)
ar = np.array([2, 5, 23, 34, 21, 42, np.nan, 25])
print(ar)
#3의 배수이거나 4의 배수인 데이터만 추출 np.nan을 제거
temp = ar[np.logical_not(np.isnan(ar))]
result = temp[(temp % 3 == 0) | (temp % 4 ==0)]
print(result)