강의상으로 중간고사 범위까지 공부를 하였다.
cs231n은 과제 3개가 있다고 해서 오늘부터 해보려고 한다.
https://cs231n.github.io/ 사이트에 들어가서 Assignment#1 부터 할 것이다.
python은 1학년 때 해보고 안 해봐서 복습을 먼저 했다.
https://cs231n.github.io/python-numpy-tutorial/ 참고
<List>
Slicing
nums = list(range(5))
print(nums) #[0,1,2,3,4] 출력
print(nums[2:4]) #[2,3] 출력
print(nums[:2]) #[0,1] 출력
print(nums[2:]) #[2,3,4] 출력
Enumerate
animals = ['cat', 'dog', 'monkey']
for idx, animal in enumerate(animals):
print('#%d: %s' % (idx + 1, animal)) # #1: cat #2: dog #3: monkey 가 각 줄에 출력
Dictionary
(key, value) 쌍으로 되어 있다
d={'cat':'cute','dog':'furry'}
print(d['cat']) #cute 출력
print('cat' in d) #True 출력
d['fish']='wet' #d에 넣기
print(d.get('monkey','N/A')) #monkey가 없으므로 'N/A' 출력
del d['fish'] #fish 삭제하기
Loop
d={'person':2, 'cat':4, 'spider':8}
for animal in d:
legs = d[animal]
print('A %s has %d legs' %(animal, legs))
for animal, legs in d.items():
print('A %s has %d legs' %(animal, legs))
위와 같이 d.items를 이용해도 된다. 두 Loop 모두 같은 결과 반환
nums =[0,1,2,3,4]
even_num_to_square = {x: x**2 for x in nums if x %2 ==0}
print(even_num_to_square)
하면 {0: 0, 2: 4, 4: 16} 출력
<Sets>
animals = {'cat', 'dog'}
print('cat' in animals)
print('fish' in animals)
animals.add('fish')
animals.remove
Loop
animals = {'cat', 'dog', 'fish'}
for idx, animal in enumerate(animals):
print('#%d: %s' % (idx + 1, animal)) # #1: fish, #2: dog, #3: cat가 출력됨 (순서 무작위)
<Tuples>
d = { (x, x+1): x for x in range(10)} #
t = (5,6)
print(type(t)) #t의 타입 출력. 결과:<class 'tuple'>
print(d[t]) #딕셔너리 d에서 t에 해당하는 값 반환. 5
print(d[(1,2)])
설명) 딕셔너리 d는 튜플 (x, x+1)을 키로 사용하고, 해당 튜플의 첫 번째 요소 x를 값으로 설정하는 딕셔너리이다.
이 딕셔너리는 0부터 9까지의 값을 가지는 x에 대해 생성된다. 예를 들어, x가 0이면 (0, 1)가 키, 값은 0이 된다.
따라서 d[(5, 6)]는 5가 된다.
import numpy as np
a=np.array([1,2,3])
print(type(a)) # <class 'numpy.ndarray'> 출력됨
print(a.shape) # a가 1차원 배열이므로 (3,) 출력. 2차원은 (m,n)으로 출력. 몇열 몇행인지
import numpy as np
a=np.zeros((2,2))
b=np.ones((1,2))
c=np.full((2,2),7) #7로 채우기
d=np.eye(2) # 1,0,0,1로 2행2열
e=np.random.random((2,2)) #0-1사이 무작위 실수
Array Indexing
a = np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12]])
b = a[:2, 1:3]
하면 b에서 :2가 의미하는 건 2번째 행까지 본다는 거다.
여기서도 0,1,2,3으로 행을 순서매기고 :2면 3번째 행 전까지 해서 첫번째, 두번째 행을 보는 거다 (2면 종료)
import numpy as np
a = np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12]])
row_r1 = a[1, :]
row_r2 = a[1:2, :]
print(row_r1, row_r1.shape)
print(row_r2, row_r2.shape)
a[1,:]에서 1이므로 두번째 행 [5 6 7 8]을 선택하고 1차원 배열이므로 shape은 (4,)이다 (1차원이면 행이 1개이므로 열만 작성)
a[1:2,:]에서 두번째 행을 선택하고 하나의 행으로 유지하기 위해 2차원 배열이 반환된다. 그래서 [[5 6 7 8]]과 같이 나오게 된다.
==> 인덱싱 vs 슬라이싱
r1같은 경우 인덱싱(특정 위치에 있는 요소를 선택)이고 r2처럼 1:2(특정 부분을 선택)하면 슬라이싱이다.
인덱싱은 1차원 슬라이싱은 2차원이다.
a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) a[:, 0:1]을 하면
[[1]
[4]
[7]] 과 같은 2차원 배열이 반환된다.
a = np.array([[1,2], [3, 4], [5, 6]])
print(a[[0, 1, 2], [0, 1, 0]])
print(np.array([a[0, 0], a[1, 1], a[2, 0]]))
print(a[[0, 0], [1, 1]])
print(np.array([a[0, 1], a[0, 1]]))
- 첫번째 print(a[[0,1,2], [0,1,0]])은 0,1,2을 첫번째 열에 0,1,0을 두번째 열에 쓰면 [0, 0], [1, 1], [2, 0]가 써진다. 이에 따라 출력한다
-세번쨰 print(a[[0,0],[1,1]])도 같은 방법으로 하면 [0,1][0,1]이 써진다.
import numpy as np
a = np.array([[1,2,3], [4,5,6], [7,8,9], [10, 11, 12]])
print(a)
# "array([[ 1, 2, 3],
# [ 4, 5, 6],
# [ 7, 8, 9],
# [10, 11, 12]])"
b = np.array([0, 2, 0, 1])
1. print(a[np.arange(4), b])
2. a[np.arange(4), b] += 10
print(a)
1. arange(4)로 배열 [0,1,2,3] 생성 == 오타아님 arange임
a[np.arange(4), b]가 의미하는 게 각 행에서 b 배열에 해당하는 열의 값을 선택하는 것(행,열)이다.
- 첫 번째 행에서는 0번째 열의 값인 1을 선택한다.
- 두 번째 행에서는 2번째 열의 값인 6을 선택한다
- 세 번째 행에서는 0번째 열의 값인 7을 선택한다
- 네 번째 행에서는 1번째 열의 값인 11을 선택한다.
2. 선택된 요소들에 10을 더한다.
[[11 2 3]
[ 4 5 16]
[17 8 9]
[10 21 12]] 이다.
a = np.array([[1,2], [3, 4], [5, 6]])
# [1,2]
# [3,4]
# [5,6]
bool_idx = (a > 2)
print(bool_idx)
print(a[bool_idx])
print(a[a > 2])
[[False False]
[ True True]
[ True True]]
[3 4 5 6]
[3 4 5 6] 가 출력 결과
DataType
import numpy as np
x = np.array([1, 2])
print(x.dtype) # int64 출력됨
Array math
-사칙연산
import numpy as np
x = np.array([[1,2],[3,4]], dtype=np.float64)
y = np.array([[5,6],[7,8]], dtype=np.float64)
# 결과:[[ 6.0 8.0]
# [10.0 12.0]]
print(x + y)
print(np.add(x, y))
# 결과: [[-4.0 -4.0]
# [-4.0 -4.0]]
print(x - y)
print(np.subtract(x, y))
# 결과: [[ 5.0 12.0]
# [21.0 32.0]]
print(x * y)
print(np.multiply(x, y))
# 결과: [[ 0.2 0.33333333]
# [ 0.42857143 0.5 ]]
print(x / y)
print(np.divide(x, y))\
# 결과: [[ 1. 1.41421356]
# [ 1.73205081 2. ]]
print(np.sqrt(x))
-행렬 곱: v.dot(w) 또는 np.dot(v,w)
v = np.array([9,10])
w = np.array([11, 12])
# Inner product of vectors; both produce 219
print(v.dot(w))
print(np.dot(v, w))
-axis 개념 잘 나옴
import numpy as np
x = np.array([[1,2],[3,4]])
print(np.sum(x, axis=0)) #열끼리 더하기 == 4 6
print(np.sum(x, axis=1)) #행끼리 더하기 == 3 7
Broadcasting
: 서로 다른 모양을 가진 배열간에 산술연산 수행
x = np.array([[1,2,3], [4,5,6], [7,8,9], [10, 11, 12]])
y = np.empty_like(x)
y[i, :] = x[i, :] + v
에서 empty_like 함수는 x와 같은 행과 열을 가지지만 채워지지 않은 상태 (공백)
나중에 연산을 통해 채워짐
x = np.array([[1,2,3], [4,5,6], [7,8,9], [10, 11, 12]])
v = np.array([1, 0, 1])
vv = np.tile(v, (4, 1))
print(vv)
y = x + vv
print(y)
이걸보면 tile함수는 반복하라는 뜻이다. 근데 (4,1)에서 4는 행을 4번 반복하라는 거고 열을 1번 반복이다
[[1 0 1]
[1 0 1]
[1 0 1]
[1 0 1]] 이게 나올 것이고
(4,2)이면
[[1 0 1 1 0 1]
[1 0 1 1 0 1]
[1 0 1 1 0 1]
[1 0 1 1 0 1]] 이게 나올 것이다.
x = np.array([[1,2,3], [4,5,6], [7,8,9], [10, 11, 12]])
v = np.array([1, 0, 1])
y = x + v
print(y)
그냥 이렇게 해도 알아서 맞춰서 x의 모든 행에 [1,0,1]이 더해진다.
reshape
import numpy as np
v = np.array([1,2,3])
w = np.array([4,5])
1. print(np.reshape(v, (3, 1)) * w)
x = np.array([[1,2,3], [4,5,6]])
2. print(x + v)
3. print((x.T + w).T)
print(x + np.reshape(w, (2, 1)))
print(x * 2)
1. reshape를 통해 재배치가 이루어진다.
print(np.reshape(v,(3,1))은 현재 1x3인 v를 3x1로 바꿔달라는 뜻이다
바꾼 상태에서 w(1x2)를 곱하면
[[ 4 5]
[ 8 10]
[12 15]] 가 나온다
2. v는 원래 [1 2 3] 이지만 재배치를 통해 x의 각 행에 더해진다.
[[2 4 6]
[5 7 9]] 가 나온다
3. x.T는 transpose 해달라는 뜻
point 간의 거리
import numpy as np
from scipy.spatial.distance import pdist, squareform
x = np.array([[0, 1], [1, 0], [2, 0]])
print(x)
d = squareform(pdist(x, 'euclidean'))
print(d)
배열이 [[0 1]
[1 0]
[2 0]] 으로 되어 있다.
첫 번째 행과 두 번째 행의 거리: sqrt((0-1)^2 + (1-0)^2) = sqrt(2) = 1.41421356
첫 번째 행과 세 번째 행의 거리: sqrt((0-2)^2 + (1-0)^2) = sqrt(5) = 2.23606798
두 번째 행과 세 번째 행의 거리: sqrt((1-2)^2 + (0-0)^2) = sqrt(1) = 1.0
따라서
[[0. 1.41421356 2.23606798]
[1.41421356 0. 1. ]
[2.23606798 1. 0. ]] 이렇게 나온다.
Matplotlib
import numpy as np
import matplotlib.pyplot as plt
x = np.arange(0, 3 * np.pi, 0.1)
y = np.sin(x)
plt.plot(x, y)
plt.show()
x = np.arange(0, 3 * np.pi, 0.1): 0부터 3π까지의 범위에서 0.1씩 증가하는 값을 생성
plt.plot(x,y)로 sin함수 그리기
import numpy as np
import matplotlib.pyplot as plt
# Compute the x and y coordinates for points on sine and cosine curves
x = np.arange(0, 3 * np.pi, 0.1)
y_sin = np.sin(x)
y_cos = np.cos(x)
# Plot the points using matplotlib
plt.plot(x, y_sin)
plt.plot(x, y_cos)
plt.xlabel('x axis label')
plt.ylabel('y axis label')
plt.title('Sine and Cosine')
plt.legend(['Sine', 'Cosine'])
plt.show()
import numpy as np
import matplotlib.pyplot as plt
x = np.arange(0, 3 * np.pi, 0.1)
y_sin = np.sin(x)
y_cos = np.cos(x)
plt.subplot(2, 1, 1)
plt.plot(x, y_sin)
plt.title('Sine')
plt.subplot(2, 1, 2)
plt.plot(x, y_cos)
plt.title('Cosine')
plt.show()
plt.subplot(2, 1, 1)은 그냥 그래프 크기, 위치 등을 조절한다 결국 위에는 sin함수 아래는 cos 함수를 그리게 된다
<참고>
1. <list와 set 차이> : 추가와 제거
List: x=[1,2,3] x.append(4) x.remove(2) 하면 2가 제거됨
Set: animals={‘cat’,’dog’} animals.add(‘lion’) animals.remove(‘cat’)
2. 튜플 -> 1차원 배열 만들기
tpl = (4, 5, 6)
arr = np.array(tpl)
print(arr)
>> [4 5 6] 출력
3. 리스트 -> 2차원 배열 만들기
lst = [[1, 2, 3], [4, 5, 6]]
arr = np.array(lst)
print(arr)
>> [[1 2 3]
[4 5 6]]
4. type 구하기
x = np.array([1, 2])
print(x.dtype) # int64 출력됨 (data type)
print(type(x)) # <class 'numpy.ndarray'> 출력됨
5. np.newaxis
In [7]: arr = np.arange(4)
In [8]: arr.shape
Out[8]: (4,)
In [9]: row_vec = arr[np.newaxis, :]
In [10]: row_vec.shape
Out[10]: (1, 4)
In [11]: col_vec = arr[:, np.newaxis]
In [12]: col_vec.shape
Out[12]: (4, 1)
<까먹지 말자>
중간에 numpy하려니까 아래와 같은 문제가 떴다.
pip install numpy / pip install -U numpy / 관리자 권한으로 terminal 실행
해도 해결이 안되었는데 cmd+shift+p ==> python interpreter를 터미널창에 있는 아나콘다3로 해주니까 실행이 되었다. 아놔...