[Numpy exercise 100] 1번 ~ 30번 문제풀이
[Numpy exercise 100] 31번 ~ 60번 문제풀이
[Numpy exercise 100] 61번 ~ 70번 문제풀이
[Numpy exercise 100] 71번 ~ 80번 문제풀이
https://github.com/rougier/numpy-100
GitHub - rougier/numpy-100: 100 numpy exercises (with solutions)
100 numpy exercises (with solutions). Contribute to rougier/numpy-100 development by creating an account on GitHub.
github.com
81. Consider an array Z = [1,2,3,4,5,6,7,8,9,10,11,12,13,14], how to generate an array R = [[1,2,3,4], [2,3,4,5], [3,4,5,6], ..., [11,12,13,14]]? (★★★)
- 어레이 Z = [1,2,3,4,5,6,7,8,9,10,11,12,13,14], 어레이 R = [[1,2,3,4], [2,3,4,5], [3,4,5,6], ..., [11,12,13,14]]를 생성하는 방법을 고려하십시오.
- 1차원 벡터를 다차원 array로 reshape. 단, 원소 한칸씩 전진하며 쌓아가야 함
- stride_tricks.as_strided : 주어진 모양 및 보폭으로 배열을 만듦
numpy.lib.stride_tricks.as_strided — NumPy v1.21 Manual
Create a view into the array with the given shape and strides. Warning This function has to be used with extreme care, see notes. as_strided creates a view into the array given the exact strides and shape. This means it manipulates the internal data struct
numpy.org
from numpy.lib import stride_tricks
Z = np.arange(1,15,dtype=np.uint32)
R = stride_tricks.as_strided(Z,(11,4),(4,4)) # 최종 shape은 (11,4)가 되도록, 보폭은 (4,4)씩
print(R)
>>>
[[ 1 2 3 4]
[ 2 3 4 5]
[ 3 4 5 6]
[ 4 5 6 7]
[ 5 6 7 8]
[ 6 7 8 9]
[ 7 8 9 10]
[ 8 9 10 11]
[ 9 10 11 12]
[10 11 12 13]
[11 12 13 14]]
82. Compute a matrix rank (★★★)
- 행렬 순위를 계산합니다
- 문제가 잘 이해는 안되지만... 특이값 분해(Singular Value Decomposition, SVD)를 사용하여 행렬을 대각화한다.
- 특이값분해 설명 블로그(다크 프로그래머 님) : https://darkpgmr.tistory.com/106
[선형대수학 #4] 특이값 분해(Singular Value Decomposition, SVD)의 활용
활용도 측면에서 선형대수학의 꽃이라 할 수 있는 특이값 분해(Singular Value Decomposition, SVD)에 대한 내용입니다. 보통은 복소수 공간을 포함하여 정의하는 것이 일반적이지만 이 글에서는 실수(real
darkpgmr.tistory.com
Z = np.random.uniform(0,1,(10,10))
U, S, V = np.linalg.svd(Z) # Singular Value Decomposition
rank = np.sum(S > 1e-10)
print(rank)
# 또 다른 방법
rank = np.linalg.matrix_rank(Z)
print(rank)
>>>
10
83. How to find the most frequent value in an array?
- 배열에서 가장 빈번한 값을 찾는 방법은 무엇입니까?
- np.bincount()를 통해서 각 값을 count한 뒤, argmax()로 가장 큰 값을 찾아냄
- argmax() : f(x)의 최대값을 만들어주는 입력 x 자체를 뜻함 (인덱스 반환)
Z = np.random.randint(0,10,50)
print(np.bincount(Z).argmax())
>>>
6
84. Extract all the contiguous 3x3 blocks from a random 10x10 matrix (★★★)
- 랜덤 10x10 행렬에서 모든 연속 3x3 블럭 추출
Z = np.random.randint(0,5,(10,10))
n = 3
i = 1 + (Z.shape[0]-3)
j = 1 + (Z.shape[1]-3)
C = stride_tricks.as_strided(Z, shape=(i, j, n, n), strides=Z.strides + Z.strides)
print(C)
>>>
[[[[1 1 1]
[4 2 0]
[4 4 4]]
[[1 1 3]
[2 0 2]
[4 4 3]]
[[1 3 2]
[0 2 0]
[4 3 3]]
...
[[4 4 2]
[4 4 4]
[3 2 4]]]]
85. Create a 2D array subclass such that Z[i,j] == Z[j,i] (★★★)
- Z[i,j] == Z[j,i]와 같은 2D 배열 하위 클래스 만들기
class Symetric(np.ndarray):
def __setitem__(self, index, value):
i,j = index
super(Symetric, self).__setitem__((i,j), value)
super(Symetric, self).__setitem__((j,i), value)
def symetric(Z):
return np.asarray(Z + Z.T - np.diag(Z.diagonal())).view(Symetric)
S = symetric(np.random.randint(0, 10, (5,5)))
S[2,3] = 42
print(S)
>>>
[[ 1 9 14 12 0]
[ 9 9 10 11 5]
[14 10 1 42 6]
[12 11 42 3 6]
[ 0 5 6 6 7]]
86. Consider a set of p matrices wich shape (n,n) and a set of p vectors with shape (n,1). How to compute the sum of of the p matrix products at once? (result has shape (n,1)) (★★★)
- 형상(n,n)이 있는 p 행렬 집합과 형상(n,1)이 있는 p 벡터 집합을 고려하십시오. p 매트릭스 제품의 합계를 한 번에 계산하는 방법은 무엇입니까? (결과에 모양(n,1)이 있음)
- np.tensordot() 공식문서 : https://numpy.org/doc/stable/reference/generated/numpy.tensordot.html
numpy.tensordot — NumPy v1.21 Manual
(2,) array_like Or, a list of axes to be summed over, first sequence applying to a, second to b. Both elements array_like must be of the same length.
numpy.org
p, n = 10, 20
M = np.ones((p,n,n))
V = np.ones((p,n,1))
S = np.tensordot(M, V, axes=[[0, 2], [0, 1]]) # np.tensordot(a, b, 축) : 지정된 축에 따라 텐서 곱을 계산
print(S)
# 추가설명... (설명해주실 분 계시면 댓글 부탁드리겠습니다ㅜㅜ)
# It works, because:
# M is (p,n,n)
# V is (p,n,1)
# Thus, summing over the paired axes 0 and 0 (of M and V independently),
# and 2 and 1, to remain with a (n,1) vector.
>>>
[[200.]
[200.]
[200.]
[200.]
[200.]
[200.]
[200.]
[200.]
[200.]
[200.]
[200.]
[200.]
[200.]
[200.]
[200.]
[200.]
[200.]
[200.]
[200.]
[200.]]
87. Consider a 16x16 array, how to get the block-sum (block size is 4x4)? (★★★)
- 16x16 array가 주어질 때, 4x4의 블록합계로 결과값을 가져오는 방법
-
- np.add.reduceat() : 주어진 배열의 인덱스를 고려하여 해당인덱스부터 끝까지의 합계를 구해 배열로 반환
-
- stride_tricks.sliding_window_view()를 이용해 합계
-
Z = np.ones((16,16))
print(Z)
k = 4
S = np.add.reduceat(np.add.reduceat(Z, np.arange(0, Z.shape[0], k), axis=0),
np.arange(0, Z.shape[1], k), axis=1)
print(S)
>>>
# Z
[[1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]]
# S
[[16. 16. 16. 16.]
[16. 16. 16. 16.]
[16. 16. 16. 16.]
[16. 16. 16. 16.]]
# sliding_window_view 사용
Z = np.ones((16,16))
k = 4
windows = np.lib.stride_tricks.sliding_window_view(Z, (k, k))
S = windows[::k, ::k, ...].sum(axis=(-2, -1))
print(S)
88. How to implement the Game of Life using numpy arrays? (★★★)
- numpy 배열을 사용하여 Game of Life를 구현하는 방법은 무엇입니까?
- Game of Life (라이프게임) 위키피디아(한글) : https://ko.wikipedia.org/wiki/%EB%9D%BC%EC%9D%B4%ED%94%84_%EA%B2%8C%EC%9E%84
라이프 게임 - 위키백과, 우리 모두의 백과사전
Hasbro의 보드 게임인 인생 게임도 가끔 ‘라이프 게임’으로 불린다. ‘글라이더’ 패턴의 진행. 라이프 게임(Game of Life) 또는 생명 게임은 영국의 수학자 존 호턴 콘웨이가 고안해낸 세포 자동자
ko.wikipedia.org
def iterate(Z):
# Count neighbours
N = (Z[0:-2,0:-2] + Z[0:-2,1:-1] + Z[0:-2,2:] +
Z[1:-1,0:-2] + Z[1:-1,2:] +
Z[2: ,0:-2] + Z[2: ,1:-1] + Z[2: ,2:])
# Apply rules
birth = (N==3) & (Z[1:-1,1:-1]==0)
survive = ((N==2) | (N==3)) & (Z[1:-1,1:-1]==1)
Z[...] = 0
Z[1:-1,1:-1][birth | survive] = 1
return Z
Z = np.random.randint(0,2,(50,50))
for i in range(100): Z = iterate(Z)
print(Z)
>>>
[[0 0 0 ... 0 0 0]
[0 0 0 ... 0 0 0]
[0 0 0 ... 0 0 0]
...
[0 0 0 ... 0 0 0]
[0 0 0 ... 0 0 0]
[0 0 0 ... 0 0 0]]
89. How to get the n largest values of an array (★★★)
- 배열의 최대값 n개를 가져오는 방법
- argsort()으로 오름차순 정렬 뒤 뒤에서 n개 가져오기 (arg가 붙으면 인덱스를 반환한다.)
- argpartition()로 배열 내 가장 작은값 (-Z로 파라미터를 주었기 때문에) n개를 찾고 인덱스 반환
Z = np.arange(10000)
np.random.shuffle(Z) # 원소 순서를 랜덤으로 섞음
n = 5
# 일반적인 방법 (전체를 sorting하므로 조금 느림)
print (Z[np.argsort(Z)[-n:]])
# 좀 더 빠른 방법 (일부만 sorting하므로)
print (Z[np.argpartition(-Z,n)[:n]])
>>>
[8178 4152 4340 ... 229 3725 3684]
[9995 9996 9997 9998 9999]
[9998 9999 9996 9997 9995]
90. Given an arbitrary number of vectors, build the cartesian product (every combinations of every item) (★★★)
- 임의의 수의 벡터가 주어지면 데카르트 곱(모든 항목의 모든 조합)을 작성합니다.
- 데카르트 곱(곱집합) : https://ko.wikipedia.org/wiki/%EA%B3%B1%EC%A7%91%ED%95%A9
곱집합 - 위키백과, 우리 모두의 백과사전
집합 A = {x, y, z}와 B = {1, 2, 3}의 곱집합 A × B. 52장의 포커 패의 집합은 모양의 집합 {♠, ♥, ♣, ♦}과 숫자의 집합 {2, ..., 10, J, Q, K, A}의 곱집합이라 생각할 수 있다. 집합론에서, 곱집합(곱集合,
ko.wikipedia.org
def cartesian(arrays):
arrays = [np.asarray(a) for a in arrays]
shape = (len(x) for x in arrays)
ix = np.indices(shape, dtype=int)
ix = ix.reshape(len(arrays), -1).T
for n, arr in enumerate(arrays):
ix[:, n] = arrays[n][ix[:, n]]
return ix
print (cartesian(([1, 2, 3], [4, 5], [6, 7])))
>>>
[[1 4 6]
[1 4 7]
[1 5 6]
[1 5 7]
[2 4 6]
[2 4 7]
[2 5 6]
[2 5 7]
[3 4 6]
[3 4 7]
[3 5 6]
[3 5 7]]
'Minding's Programming > Numpy & Pandas' 카테고리의 다른 글
[Numpy Exercise 100] 91번 ~ 100번 문제풀이 (0) | 2022.01.03 |
---|---|
[Numpy exercise 100] 71번 ~ 80번 문제풀이 (0) | 2021.12.28 |
[Numpy exercise 100] 61번 ~ 70번 문제풀이 (0) | 2021.12.27 |
[Numpy exercise 100] 31번 ~ 60번 문제풀이 (0) | 2021.12.24 |
[Numpy exercise 100] 1번 ~ 30번 문제풀이 (0) | 2021.12.23 |