>>> import urllib.request as req
import re
>>> req.urlopen("http://daum.net") #urlopen() : url 접속
>>> req.urlopen("http://daum.net").read() #url 코드를 가져온다
>>> data = req.urlopen("http://daum.net").read().decode("utf-8")
data #data 전체를 '한 문장' 취급한다
#'https'로 시작해서 'js'로 끝나는 것만 출력
>>> p = re.compile("https://\S+[.]js")
li = p.findall(data)
for i in li:
print(i)
>>> p = re.compile("https[:./\w]*[.]js")
li = p.findall(data)
for i in li:
print(i)
#[:./\w] : [] 안에 들어가면 메타 문자의 특성을 갖지 않는다
#':', '.', '/', '\w' 하나하나로 인식한다
>>> webp = '''<div class="faZHB"><a href="#" target="_self" role="button" aria-expanded="true" class="M_704" style="display: block;"><span class="WoYOw">이른 아침 문을 여는 빵집입니다. 아침식사로 빵을 사러 가기엔 좋지만 매장안에서 드실 공간은 없어요. 이 빵집은 특이하게도 물 또는 커피를 무료로 텀블러에 담아갈수 있습니다. 가볍게 아침을 해결하고자 하는 여행자나 현지인은 들러보면 좋을 장소입니다. 참고로, 식빵 나오는 시간은 오전11시~12시 입니다. 빵 가격은 가성비 괜찮은 편이고 맛은 무난합니다. </span></a></div><div class="faZHB"><a href="#" target="_self" role="button" aria-expanded="false" class="M_704" style="display: block;"><span class="WoYOw">우연히 들어갔는데 사장님이 따뜻하고 친절하셔서 제주도 이미지마저 좋게 느껴졌어요. 그리고 무엇보다 빵이 정말 맛있어요. 제주도에서 원탑입니다!!! 여기보다 두배는 ...</span><span class="_3_09q"><svg xmlns="
http://www.w3.org/2000/svg
" viewBox="0 0 12 7" class="_3Dnsh" aria-hidden="true"><path d="M11.47.52a.74.74 0 0 0-1.04 0l-4.4 4.45v.01L1.57.52A.74.74 0 1 0 .53 1.57l5.12 5.08a.5.5 0 0 0 .7 0l5.12-5.08a.74.74 0 0 0 0-1.05z"></path></svg><span class="place_blind">내용 더보기</span></span></a></div><div class="faZHB"><a href="#" target="_self" role="button" aria-expanded="false" class="M_704" style="display: block;"><span class="WoYOw">맛집검색하다가 스쳐지나갔는데 숙소근처에 있길래 들렸어요!! 시식하는빵도 있고 빵구매하는데 서비스로 흰색찹살떡??도 주시고 친절하세요! 인절미빵 강추입니다! ...</span><span class="_3_09q"><svg xmlns="
http://www.w3.org/2000/svg
" viewBox="0 0 12 7" class="_3Dnsh" aria-hidden="true"><path d="M11.47.52a.74.74 0 0 0-1.04 0l-4.4 4.45v.01L1.57.52A.74.74 0 1 0 .53 1.57l5.12 5.08a.5.5 0 0 0 .7 0l5.12-5.08a.74.74 0 0 0 0-1.05z"></path></svg><span class="place_blind">내용 더보기</span></span></a></div><div class="faZHB"><a href="#" target="_self" role="button" aria-expanded="false" class="M_704" style="display: block;"><span class="WoYOw">인절미빵. 먹물치즈빵? 제일 맛있었고 대파빵은 삼겹살을 부르는 꽤 매운 맛이었어요! 빵이 대체로 다~~~~맛있고 친절하십니다 주차는 근처 공영주차장에 하면 됩니다 다...</span><span class="_3_09q"><svg xmlns="
http://www.w3.org/2000/svg
" viewBox="0 0 12 7" class="_3Dnsh" aria-hidden="true"><path d="M11.47.52a.74.74 0 0 0-1.04 0l-4.4 4.45v.01L1.57.52A.74.74 0 1 0 .53 1.57l5.12 5.08a.5.5 0 0 0 .7 0l5.12-5.08a.74.74 0 0 0 0-1.05z"></path></svg><span class="place_blind">내용 더보기</span></span></a></div><div class="faZHB"><a href="#" target="_self" role="button" aria-expanded="false" class="M_704" style="display: block;"><span class="WoYOw">사진을 제대로 못찍엇는데 뒤에 비닐로 싸진 빵들이에요 ㅋㅋㅋ 여기 진짜 촤고에요 보니 동네찐로컬맛집같아요 빵종류도 많고 각 빵마다 시식빵이 있는데 크기가 넘 커서...</span><span class="_3_09q"><svg xmlns="
http://www.w3.org/2000/svg
" viewBox="0 0 12 7" class="_3Dnsh" aria-hidden="true"><path d="M11.47.52a.74.74 0 0 0-1.04 0l-4.4 4.45v.01L1.57.52A.74.74 0 1 0 .53 1.57l5.12 5.08a.5.5 0 0 0 .7 0l5.12-5.08a.74.74 0 0 0 0-1.05z"></path></svg><span class="place_blind">내용 더보기</span></span></a></div><div class="faZHB"><a href="#" target="_self" role="button" aria-expanded="false" class="M_704" style="display: block;"><span class="WoYOw">성산 여행하는 동안 두번이나 방문했어요 빵도 특색있고 하나하나 다 맛있고 사장님도 직원분도 친절하시고 커피도 무료로 먹을수 있게 해주시고 살때마다 서비스빵을 주...</span><span class="_3_09q"><svg xmlns="
http://www.w3.org/2000/svg
" viewBox="0 0 12 7" class="_3Dnsh" aria-hidden="true"><path d="M11.47.52a.74.74 0 0 0-1.04 0l-4.4 4.45v.01L1.57.52A.74.74 0 1 0 .53 1.57l5.12 5.08a.5.5 0 0 0 .7 0l5.12-5.08a.74.74 0 0 0 0-1.05z"></path></svg><span class="place_blind">내용 더보기</span></span></a></div><div class="faZHB"><a href="#" target="_self" role="button" aria-expanded="false" class="M_704" style="display: block;"><span class="WoYOw">사장님 너무 친절하시고 빵이 진짜 맛있어요.. 미친 맛,,,,🥹가격이 타 빵집보다 훠얼씬 저렴한데 맛이 훠얼씬 맛있네요,,,??!?! 저희 동네에 있었음 매일 가고싶네요ㅠㅠㅠ …</span><span class="_3_09q"><svg xmlns="
http://www.w3.org/2000/svg
" viewBox="0 0 12 7" class="_3Dnsh" aria-hidden="true"><path d="M11.47.52a.74.74 0 0 0-1.04 0l-4.4 4.45v.01L1.57.52A.74.74 0 1 0 .53 1.57l5.12 5.08a.5.5 0 0 0 .7 0l5.12-5.08a.74.74 0 0 0 0-1.05z"></path></svg><span class="place_blind">내용 더보기</span></span></a></div><div class="faZHB"><a href="#" target="_self" role="button" aria-expanded="false" class="M_704" style="display: block;"><span class="WoYOw">재료를 아끼지 않으세요 눚은시간 방문했는데도 손님들이 꽤 왔어요 마늘바게트에는 소스를 아끼지 않았고 다른빵들도 크림이 듬뿍 들어 있었어요 서비스도 주시고 시식…</span><span class="_3_09q"><svg xmlns="
http://www.w3.org/2000/svg
" viewBox="0 0 12 7" class="_3Dnsh" aria-hidden="true"><path d="M11.47.52a.74.74 0 0 0-1.04 0l-4.4 4.45v.01L1.57.52A.74.74 0 1 0 .53 1.57l5.12 5.08a.5.5 0 0 0 .7 0l5.12-5.08a.74.74 0 0 0 0-1.05z"></path></svg><span class="place_blind">내용 더보기</span></span></a></div>'''
#영어 빼고 한글만 출력
>>> p = re.compile("[가-힣].+[가-힣]") #한글로 시작해서 한글로 끝나는 것 (중간은 뭐가 있어도 상관없다)
li = p.findall(webp)
li
>>> p = re.compile("[^가-힣0-9\s.~]")
e = p.sub("", webp)
e
>>> re.sub("\s\d+[.]\d+", "", e)
>>> p = re.compile("[가-힣\s.~!]+")
li = p.findall(webp)
for i in li:
if i != '':
print(i)
"010[-]\d{4}[-]\d{4}"
"\d{2,3}[-]\d{4}[-]\d{4}"
#prince@naver.com
#hello@daum.net
#morning@company.co.kr
"[A-z0-9]+@[A-z0-9]+[.][a-z.]+"
".+@[a-z0-9]+[.][a-z]+"
"\d{6}-\d{7}"
"\d{6}-[1-6]\d{6}"
\n를 제외한 모든 문자와 매치된다\n문자도 포함하여 매치하고 싶다면 re.DOTALL (또는 re.S) 옵션을 사용하여 정규식을 컴파일 한다>>> p = re.compile('a.b', re.DOTALL)
m = p.match('a\nb')
print(m)
<re.Match object; span=(0, 3), match='a\nb'>
>>> import re
>>> p = re.compile("^python\s\w+", re.MULTILINE)
data = """python one
life is too short
python two
you need python
python three"""
print(p.findall(data))
['python one', 'python two', 'python three']
>>> text1 = '''
http://www.google.com/
https://mail.google.com/
ftp://ftp.google.com/
'''
#['http:', 'https:', 'ftp:']
>>> p = re.compile(".+:")
p.findall(text1)
['http:', 'https:', 'ftp:'] #먼저 ['http:', 'https:', 'ftp:']를 출력한 후
#['http', 'https', 'ftp']
>>> p = re.compile(".+(?=:)")
p.findall(text1)
['http', 'https', 'ftp'] #전방 탐색을 해서 ':'를 제거한다
>>> text2 = '''apple: $50.24
banana: $35.25
pizza: $100
'''
#['50.24', '35.25', '100']
>>> p = re.compile("[$].+") #[$] 는 \$ 로 표기할 수도 있다
p.findall(text2)
['$50.24', '$35.25', '$100'] #먼저 $숫자 부분을 출력한 후
>>> p = re.compile("(?<=[$]).+") #후방 탐색을 해서 '$'를 제거한다
p.findall(text2)
text3 = '''<p>이른 아침 문을 여는 빵집입니다</p>
<h1>아침식사로 빵을 사러 가기엔 좋지만 매장안에서 드실 공간은 없어요</h1>
<h5>이 빵집은 특이하게도 물 또는 커피를 무료로 텀블러에 담아갈수 있습니다</h5>
<p>가볍게 아침을 해결하고자 하는 여행자나 현지인은 들러보면 좋을 장소입니다</p>
<p>참고로 식빵 나오는 시간은 오전9시 입니다</p>
'''
#<p> 와 </p> 사이의 글
>>> p = re.compile("(?<=<p>).+(?=</p>)")
p.findall(text3) #<p> 뒤를 후방탐색, </p> 앞을 전방탐색 -> 한번에
['이른 아침 문을 여는 빵집입니다',
'가볍게 아침을 해결하고자 하는 여행자나 현지인은 들러보면 좋을 장소입니다',
'참고로 식빵 나오는 시간은 오전9시 입니다']
-"the core library"
-"a high performance"
-2차원에서
axis 0 : x축
axis 1 : y축
-3차원에서
axis 0 : z축
axis 1 : y축
axis 2 : x축
강력한 N차원 배열 객체, List 보다 빠르다 (파이썬은 느리다)
빠른 이유
-python 코드가 아니라 C코드로 작성되어 있어서
-메모리 저장구조가 달라서
-반복문을 사용하지 않고, 배열을 통해 바로 계산되어서
-벡터라이즈와 브로드캐스팅을 사용해서
각 차원을 축(axis)라고 한다
배열의 차원은 'shape'라고 하고, tuple로 표시한다 -> (3, ), (2, 3)
shape 안의 숫자는 각 차원에 있는 원소의 개수
전체 원소의 개수는 'size'
-array 함수는 np 라이브러리에 들어있다
-입력값으로 '리스트' 가 들어간다
-동일한 데이터형 이어야 한다
>>> import numpy as np
>>> a = np.array([0,1,2,3]) #입력값으로 리스트가 들어간다
a
array([0, 1, 2, 3])
>>> print(a)
[0 1 2 3] #array가 아닌 리스트로 착각할 수 있다
>>> print(a.shape) #각 차원에 있는 원소의 개수
print(a.size) #전체 원소의 개수
print(a.dtype)
print(a.ndim)
(4,)
4
int32
1
>>> li = [0,1,2,3]
np.array(li)
array([0, 1, 2, 3])
>>> a= np.array([1, 2, 3, 4])
a.dtype
dtype(‘int64')
>>> a = np.array([0,1,2,3,4.3])
a.dtype
dtype('float64') #8 bit = 1 byte => 64bit = 8byte
#데이터형은 자동으로 할당된다
>>> a = np.array([0,1,2,3,4.3], dtype = 'int')
a.dtype
dtype('int32')
>>> a
array([0, 1, 2, 3, 4])
>>> a = np.array([0,1,2,3], dtype ='float')
a
array([0., 1., 2., 3.])
>>> a.dtype
dtype('float64')
>>> a = np.array([0,1,2,3], dtype ='float32')
a.dtype
dtype('float32')
>>> a = np.array([0,1,2,3], dtype ='float16')
a.dtype
dtype('float16')
>>> a = np.array([0,1,2,3], dtype ='float8')
a.dtype
TypeError: data type 'float8' not understood
>>> a = np.array([0,1,2,3], dtype ='int8') #int8 : byte (-128 to 127)
a.dtype
dtype('int8')
>>> list1 = [1,2,3,4]
list2 = [1,2,3,4]
list1 + list2
[1, 2, 3, 4, 1, 2, 3, 4]
#python
>>> list1 = [1,2,3,4]
list2 = [1,2,3,4]
list3 = []
for i in range(4):
list3.append(list1[i] + list2[i])
list3
[2, 4, 6, 8]
#numpy
>>> array1 = np.array([1,2,3,4])
array2 = np.array([1,2,3,4])
array3 = array1 + array2
array3
array([2, 4, 6, 8])
#python
>>> def add_list(n):
li1 = list(range(1, n+1))
li2 = list(range(1, n+1))
li3 = []
for i in range(n):
li3.append(li1[i] + li2[i])
return li3
>>> add_list(10)
[2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
#numpy
>>> def add_array(n):
ar1 = np.array(range(1, n+1))
ar2 = np.array(range(1, n+1))
ar3 = ar1 + ar2
return ar3
>>> add_array(10)
array([ 2, 4, 6, 8, 10, 12, 14, 16, 18, 20])
>>> def add_list():
li1 = list(range(1, 101))
li2 = list(range(1, 101))
li3 = []
for i in range(100):
li3.append(li1[i] + li2[i])
return li3
>>> add_list()
>>> def add_array():
ar1 = np.array(range(1, 101))
ar2 = np.array(range(1, 101))
ar3 = ar1 + ar2
return ar3
>>> add_array()
>>> import timeit
>>> li1 = list(range(10000))
li2 = list(range(10000))
def add_list():
li3 = []
for i in range(10000):
li3.append(li1[i] + li2[i])
return li3
>>> print(timeit.timeit(add_list, number=10000))
>>> ar1 = np.array(range(10000))
ar2 = np.array(range(10000))
def add_array():
ar3 = ar1 + ar2
return ar3
>>> print(timeit.timeit(add_array, number=10000))
-np.array( )함수를 써서 만들기
-arange( )와 reshape( )를 써서 만들기
>>> np.array([[1,2,3,4], [5,6,7,8]]) #대괄호 2개(중첩리스트) -> 2차원
array([[1, 2, 3, 4],
[5, 6, 7, 8]])
>>> np.arange(10)
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> np.arange(10).reshape((2, 5))
#arange(10) -> 1행 10열 (1X10)
#.reshape(2, 5) -> 2행 5열로 변경 (2*5 = 10)
array([[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9]])
>>> np.arange(12).reshape(3, 4)
>>> np.arange(12).reshape(3, -1)
#'-1' -> 3이 입력되어있기 때문에 4를 입력하지 않아도 자동으로 처리해준다
>>> np.arange(24).reshape(2,3,4) #3행 4열이 2장 나온다 (z, y, x)
>>> np.arange(24).reshape(3,4,2)
>>> np.arange(36).reshape(3,4,3)
리스트의 연산과 비슷하지만, 약간 다르다
numpy 함수를 쓰는 것보다 '객체.함수( )' 가 편리하다
Numpy의 연산은 원소들끼리 이루어진다 -> "element wise"
array의 형태(shape)가 안 맞으면, 자동으로 맞추어 주기도 한다 -> "broadcasting"
>>> a = np.array([[1,2], [3,4]])
b = np.array([[5,6], [7,8]])
>>> a + b
[[ 6 8]
[10 12]]
>>> a ** b #거듭제곱도 가능하다
[[ 1 64]
[ 2187 65536]]
-브로드캐스팅(Broadcasting) 이란
차원(dimension)이 다른 두 배열의 연산에서
낮은 차원의 배열이 차원을 맞추어 주도록 변화한다
데이터의 복사를 하지 않으므로 빠르다
적어도 행과 열 중에 어느 한쪽의 형태는 같아야 한다
>>> a = np.array([[1,2], [3,4]])
c = np.array([5,6])
>>> a + c
array([[ 6, 8],
[ 8, 10]])
>>> d = np.array([5])
a + d
array([[6, 7],
[8, 9]])
>>> a + 6
array([[ 7, 8],
[ 9, 10]])
>>> e = np.array([5,6,7])
a + e
ValueError: operands could not be broadcast together with shapes (2,2) (3,)
>>> a = np.array([[1,2,3], [4,5,6]])
c = np.array([5,6])
a + c
ValueError: operands could not be broadcast together with shapes (2,3) (2,)
>>> a = np.array([[1,2,3,4], [5,6,7,8]])
c = np.array([5,6])
a + c
ValueError: operands could not be broadcast together with shapes (2,4) (2,)
>>> a = np.array([[1,2], [3,4], [5,6],[7,8]])
c = np.array([5,6])
a + c
array([[ 6, 8],
[ 8, 10],
[10, 12],
[12, 14]])
>>> a = np.arange(25).reshape(5, 5)
a
#array([20, 21, 22, 23, 24]) 출력
>>> a[4,:]
>>> a[:,(1,3)]
>>> a[(1,3),(0,2)]
>>> a = np.array([1,2,3,4])
a + np.array([1,2]) #불가능
ValueError: operands could not be broadcast together with shapes (4,) (2,)
>>> np.array([[1],[2]])
array([[1],
[2]])
>>> a + np.array([[1],[2]]) #가능
array([[2, 3, 4, 5],
[3, 4, 5, 6]])