상세 컨텐츠

본문 제목

[ Numpy 100제 ] 11 ~ 20 번

Python/Numpy

by teang1995 2021. 10. 2. 12:33

본문

반응형

numpy 핸들링에 익숙해져야 한다고 생각해서.. 마침 누군가 잘 만들어둔 numpy 100제 문제가 있어 조금씩 풀어보려 한다.

문제 링크 : link
내 코드 : link

11. Create a 3x3 identity matrix

a = np.eye(3)
a
'''
array([[1., 0., 0.],
       [0., 1., 0.],
       [0., 0., 1.]])
'''

어렵지 않다.

12. Create a 3x3x3 marray with random values

a = np.random.rand(3, 3, 3)
a
'''
array([[[0.02571122, 0.46360895, 0.01516786],
        [0.53682388, 0.43733759, 0.26646065],
        [0.53369816, 0.13297916, 0.26736495]],

       [[0.80098917, 0.54256621, 0.70453408],
        [0.44868314, 0.41217662, 0.91169197],
        [0.15444328, 0.93293728, 0.42223692]],

       [[0.02168339, 0.08950227, 0.68668666],
        [0.11584576, 0.84057744, 0.79697318],
        [0.69573145, 0.12360324, 0.47822939]]])
'''

아아.. 얼마나 코드를 안 짜봤는지 알 수 있는 대목.
이걸 몰라서 도큐먼트를.. 아무튼 함수 하나로 해결할 수 있었다.

13. Create a 10x10 array with random values and the minimun and maximum values

a = np.random.rand(10, 10)
max_ = np.max(a)
min_ = np.min(a)
print(max_, min_)
a

'''
0.9996805212200861 0.000854861256604722

array([[5.97675478e-02, 7.45091413e-01, 5.92583825e-01, 2.27910643e-01,
        1.70055217e-01, 8.54861257e-04, 5.30175290e-01, 4.85350130e-01,
        3.21096804e-01, 7.87677932e-01],
       [8.25019395e-01, 9.99680521e-01, 1.44990247e-01, 3.29949724e-01,
        4.47902070e-01, 9.49597561e-01, 9.42434042e-01, 8.98169316e-01,
        8.69085103e-01, 7.24541790e-01],
       [6.85659477e-01, 8.01166964e-01, 7.08921406e-01, 7.11774906e-02,
        4.98084132e-01, 7.82500577e-01, 4.80382917e-01, 1.95007356e-01,
        2.22983069e-01, 3.80973317e-01],
       [4.04131338e-01, 3.61276114e-02, 1.47489541e-02, 8.04400059e-01,
        3.32202070e-01, 8.27770605e-02, 7.47520366e-01, 1.92595026e-01,
        6.55529269e-01, 9.90990323e-01],
       [6.86534346e-01, 1.95431785e-01, 1.66977874e-01, 3.98129065e-01,
        1.56998327e-01, 7.34323526e-01, 9.88089902e-01, 6.03100221e-01,
        1.76506922e-02, 9.41845161e-01],
       [8.80081614e-01, 7.21377191e-01, 9.10645643e-01, 1.86331458e-01,
        6.11190029e-01, 7.57794811e-02, 8.63705525e-01, 4.87061085e-01,
        7.09425298e-02, 3.58110524e-01],
       [1.76308391e-01, 7.74758182e-01, 8.18984048e-01, 5.53928703e-02,
        5.58254159e-01, 3.26708603e-01, 7.83712725e-02, 3.45436837e-01,
        4.45074405e-01, 9.57165057e-01],
       [5.56337405e-01, 7.33152629e-01, 6.99682220e-01, 6.26973578e-01,
        3.10440599e-02, 4.41020235e-01, 9.96273318e-01, 6.67459843e-01,
        2.29710801e-01, 6.54466833e-01],
       [5.45555279e-02, 9.79145108e-01, 3.04840276e-01, 1.78806378e-01,
        4.87668212e-01, 3.23822228e-01, 1.10603437e-01, 4.06774961e-01,
        3.26217799e-01, 3.97474314e-01],
       [6.30405161e-01, 3.37266380e-01, 9.01114335e-01, 5.46503808e-01,
        5.24283672e-01, 9.37761589e-01, 8.27241339e-02, 5.24613007e-02,
        5.08427410e-01, 2.64412844e-01]])
'''

어렵지 않게 구할 수 있었다.
문제 솔루션에선 a.max(), a.min()을 사용했다.
중요한 이슈는 아니니 패스.

14. Create a random vector of size 30 and find the mean value

a = np.random.rand(30)
print(np.mean(a))
a
'''
0.4666505351630892
'''

파이썬 공부하기 전에 감명깊었던 대사는 바로
'C언어는 이것도 안 되겠어? 하면 안 되고, 파이썬은 이게 되겠어? 하면 어지간하면 된다.'라는 이야기였다.
딱 거기에 부합한 문제. 아마 있을 것이라 생각하고 써보았더니 있더라.

15. Create a 2d arrray with 1 on the border and 0 insde


# my solution
a = np.zeros((4, 4))
print(a)
a = np.pad(a, ((1, 1), (1, 1)), 'constant', constant_values=1)
print(a)
'''
[[0. 0. 0. 0.]
 [0. 0. 0. 0.]
 [0. 0. 0. 0.]
 [0. 0. 0. 0.]]
[[1. 1. 1. 1. 1. 1.]
 [1. 0. 0. 0. 0. 1.]
 [1. 0. 0. 0. 0. 1.]
 [1. 0. 0. 0. 0. 1.]
 [1. 0. 0. 0. 0. 1.]
 [1. 1. 1. 1. 1. 1.]]
'''

# solution
a = np.ones((6, 6))
a[1:-1, 1:-1] = 0
a

'''
array([[1., 1., 1., 1., 1., 1.],
       [1., 0., 0., 0., 0., 1.],
       [1., 0., 0., 0., 0., 1.],
       [1., 0., 0., 0., 0., 1.],
       [1., 0., 0., 0., 0., 1.],
       [1., 1., 1., 1., 1., 1.]])
'''

어, 예쁘다.
언제쯤이면 array indices를 맘대로 가지고 놀까? 참 깔끔하다.
답지의 풀이 방법은 모두 1로 선언한 뒤, 1부터 -2번째까지 인덱스를 0으로 채우는 것.
이게 훨 직관적이고 나은 풀이 같다.

16. How to add a border around an existing array?

# my solution
a = np.zeros((4, 4))
print(a)
a = np.pad(a, ((1, 1), (1, 1)), 'constant', constant_values=1)
print(a)

# fancy solution
Z = np.ones((6, 6))
Z[:, [0, -1]] = 0
Z[[0, -1], :] = 0
print(Z)

윗 문제랑 좀 다른 점이 있다면, 위 친구는 shape을 정해준 뒤 테두리를 만들어라였다면,
16번 문제는 어떤 모양이 들어와도 padding을 해줘라 이런 것 같다.

문제 풀이도 조금 달라지는데, 아랫 문제의 풀이는 정말 테두리를 그리는 느낌..
x, y축을 타고 가면서 0, -1번째 indices를 가지는 성분만 순서대로 0으로 바꿔주는 방법. 배웠다.

17. What is the result of the following expression?

0 * np.nan
np.nan == np.nan
np.inf > np.nan
np.nan - np.nan
np.nan in set([np.nan])
0.3 == 3 * 0.1
'''
np.nan
False
False
error? -> nan
False -> True
False
'''

np.nan은 계산되지 않는다.
근데 또 set으로는 잡히네..

18. Create a 5x5 matrix with values 1,2,3,4 just velow the diagonal

a = np.diag(1 + np.arange(4), k=-1)
a

np.diag의 전혀 새로운 사용법.
np.diag document

a = np.diag(1 + np.arange(6), k = 3)
a
# 아하, k를 늘리면 이 성분들을 main diagonal 의 k 번째 위에, 혹은 아래에 올릴 수 있게끔 array shape을 맞추어주는구나.
'''
array([[0, 0, 0, 1, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 2, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 3, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 4, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 5, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 6],
       [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]])
'''

19. Create 3x3 matrix with values ranging from 0 to 8

a = np.zeros((8, 8), dtype=int)
a[1::2, 0::2] = 1 # y축으로 1행부터 시작해서 두 칸에 한 번씩 1로 채운다. 단, x축으로는 0번째 열부터 두 열에 한 번씩
a[0::2, 1::2] = 1 # y축으로 0행부터 시작해서 두 칸에 한 번씩 1로 채운다. 단, x축으로는 1번째 열부터 두 열에 한 번씩
a
'''
array([[0, 1, 0, 1, 0, 1, 0, 1],
       [1, 0, 1, 0, 1, 0, 1, 0],
       [0, 1, 0, 1, 0, 1, 0, 1],
       [1, 0, 1, 0, 1, 0, 1, 0],
       [0, 1, 0, 1, 0, 1, 0, 1],
       [1, 0, 1, 0, 1, 0, 1, 0],
       [0, 1, 0, 1, 0, 1, 0, 1],
       [1, 0, 1, 0, 1, 0, 1, 0]])
'''

인덱스로 다 했다. 멋지네.
좀 알 것 같기도 하다.

a[1::2, 0::2]는 y축으로는 홀수번째, x축으로는 짝수번째인 친구들만 1을 채워주는 것.
a[0::2, 1::2]는 y축으로는 짝수번째, x축으로는 홀수번째인 친구들만 1을 채워주는 것.

20. Consider a (6, 7, 8) shape array, what is the index (x, y, z) of the 100th element?

np.unravel_index(99, (6, 7, 8))

np.unravel_index document

np.unravel_index(indices, shape, order='C')

Parameters

indices: array_like An integer array whose elements are indices into the flattened version of an array of dimensions shape.

shape: tuple of ints The shape of the array to use for unraveling indices.

order : {'C', 'F'}, optional, default='C' Determines whether the indices should be viewed as indexing in row-major (C-style) or column-major (Fortran-style) order.

별 게 다 있다.
shape인자에 들어온 친구를 flatten했을 indices 의 위치에 존재하는 친구는, 기존 array에서 어떤 위치에 존재할까?
에 답하는 함수이다.

간단히 사용법을 찾아보았는데,

np.unravel_index(10, (3, 7)) 
# 아하, shape 인자의 shape을 가지는 array를 flatten시켰을 때 
# indices에 있는 친구들이 기존 array에서 어떤 위치에 있는지를 보는 거구나.
'''
'''
(1, 3)

간단하게는 위와 같이 일차원 array에서 사용할 수도 있고

np.unravel_index([99, 100], (6, 7, 8))
# indices에 여러 개의 인자를 넣어주면 각 축의 좌표들을 반환해주는구나.
'''
(array([1, 1]), array([5, 5]), array([3, 4]))
'''

indices에 여러 개의 인자를 리스트로 줄 수도 있다.
축을 따라가면서 좌표를 반환해주니 주의하자.

np.unravel_index(99, (6, 7, 8), order='F')
# order를 column-major로 바꾸어주었더니 반환되는 인덱스가 달라지는 것을 확인할 수 있다.
'''
(3, 2, 2)
'''

같은 indices를 넣어줬는데 문제와 반환값이 다르다.
이는 order 에 'F'를 주었기 때문.
docuemnt를 보면 알겠지만 default 는 'C'인데
'C'와 'F'는 각각 행 우선, 열 우선 계산법을 의미한다.
직관적이지 못 해 'F'는 사용하지 않을 듯 하다.

'Python > Numpy' 카테고리의 다른 글

[ Numpy 100제 ] 41 ~ 50 번  (0) 2022.01.30
[ Numpy 100제 ] 31~40 번  (0) 2022.01.30
[ Numpy 100제 ] 21 ~ 30 번  (0) 2021.10.06
[ Numpy 100제 ] 01 ~ 10 번  (0) 2021.10.01

관련글 더보기

댓글 영역