상세 컨텐츠

본문 제목

[ Numpy 100제 ] 21 ~ 30 번

Python/Numpy

by teang1995 2021. 10. 6. 01:51

본문

반응형

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

문제 링크 : link
내 코드 : link


21. Create a checkerboard 8x8 matrix using the tile function.

Explore np.tile

np.info('tile')
     *** Found in numpy ***
 tile(A, reps)

Construct an array by repeating A the number of times given by reps.

If `reps` has length ``d``, the result will have dimension of
``max(d, A.ndim)``.

If ``A.ndim < d``, `A` is promoted to be d-dimensional by prepending new
axes. So a shape (3,) array is promoted to (1, 3) for 2-D replication,
or shape (1, 1, 3) for 3-D replication. If this is not the desired
behavior, promote `A` to d-dimensions manually before calling this
function.

If ``A.ndim > d``, `reps` is promoted to `A`.ndim by pre-pending 1's to it.
Thus for an `A` of shape (2, 3, 4, 5), a `reps` of (2, 2) is treated as
(1, 1, 2, 2).

Note : Although tile may be used for broadcasting, it is strongly
recommended to use numpy's broadcasting operations and functions.

Parameters
----------
A : array_like
    The input array.
reps : array_like
    The number of repetitions of `A` along each axis.

Returns
-------
c : ndarray
    The tiled output array.

See Also
--------
repeat : Repeat elements of an array.
broadcast_to : Broadcast an array to a new shape

My code

a = np.array([[1, 0], [0, 1]])
np.tile(a, (4, 4)) # awesome
'''
array([[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],
       [0, 1, 0, 1, 0, 1, 0, 1]])
'''

22. Normalize a 5x5 random matrix

a = np.random.rand(5, 5)
norm = np.mean(a)
std = np.std(a)
b = (a  - norm) / std
b

그.. 어떤 normalization인지는 말해줘야 하는 거 아님까?
L2norm 때리려다가 답지 보니 전혀 달라서 당황스러웠다.

23. Create a custom dtype that describes a color as four unsigned bytes (RGBA)

color = np.dtype([("r", np.ubyte),
                  ("g", np.ubyte),
                  ("b", np.ubyte),
                  ("a", np.ubyte)])

이거 어떻게 쓰는 거지?? 전혀 모르겠다..

24. Multiply a 5x3 matrix by a 3x2 matrix (real matrix product)

a = np.random.rand(5, 3)
b = np.random.rand(3, 2)
a@b
'''
array([[0.3047514 , 0.66470621],
       [0.33125251, 0.71317578],
       [0.53102109, 1.19473105],
       [0.50655334, 1.11133575],
       [0.38128635, 0.89329339]])
'''

어렵지 않다. 그냥 하면 된다!

25. Given a 1D array, negate all elements which are between 3 and 8, in place.

a = np.arange(11)
mask = (3 < a) & (a < 8)
mask
a[mask] *= -1
a
'''
array([ 0,  1,  2,  3, -4, -5, -6, -7,  8,  9, 10])
'''

마스크 구해주고, 해당 마스크를 인덱스로 잡은 성분들에 -1을 곱해주면 된다.

26. What is the output of the following script?

print(sum(range(5),-1))
from numpy import *
print(sum(range(5),-1)) # ?
'''
9
10
'''

아하. python의 내장함수인 sum에서는 offset?을 설정하는 인자가 숨어있었다.
numpy에서는 다들 알 듯이 -1을 넣어주면 axis의 값을 의미하는 것이고..
python sum
numpy sum

그래서 sum(range(5), -1) 을 넣어주면 -1에다가 10을 더한다.

27. 패스

28. What are the result of the following expressions?

print(np.array(0) / np.array(0))
print(np.array(0) // np.array(0))
print(np.array([np.nan]).astype(int).astype(float))
'''
nan
0
[-9.22337204e+18]
'''

0을 0으로 그냥 나누면 nan이, 몫을 구하면 0이 나온다.
알아두면 나중에 trouble shooting에 사용될 일이 한 번은 꼭 있을 것 같다.
np.nan 을 값으로 바꾼 예제인데.. 사용할 일이 있을까?

29. How to round away from zero a float array ?

Z = np.random.uniform(-10,+10,10)
print(Z)
print(np.copysign(np.ceil(np.abs(Z)), Z))

# More readable but less efficient
print(np.where(Z>0, np.ceil(Z), np.floor(Z)))
# 0보다 크면 올림, 작으면 내림.
'''
[-5.99734733 -6.33925253  6.3920537   4.3773532   6.29985978 -5.5348404
 -6.88693061  1.0596027  -4.55241316 -9.32123542]
[ -6.  -7.   7.   5.   7.  -6.  -7.   2.  -5. -10.]
[ -6.  -7.   7.   5.   7.  -6.  -7.   2.  -5. -10.]
'''

np.copysign
유용할 것 같은 친구를 알았다.
np.copysign(x1, x2)를 사용하면 x2의 부호를 그대로 x1에 적용할 수 있다.
물론 둘의 shape은 같거나, broadcasting 될 수 있게 맞추어져 있어야 한다.

np.where
이것도 보물이다.
np.where에는 3항연산자 같은 역할을 하게끔 해주는 인자가 있었다.
np.where(condition, [x, y]에서
condition이 true면 x를, false 면 y를 각 인덱스의 성분에 적용한다.

30. How to find common values between two arrays?

a = np.arange(1, 10)
b = np.arange(5, 20)
print(np.intersect1d(a, b, return_indices=True))
# return_indices 옵션을 주면 (intersect_values, indices of values at a, indices of values at b) 순으로 반환된다.

# return_indices=False
# array([5, 6, 7, 8, 9])

# return_indices=True
# (array([5, 6, 7, 8, 9]), array([4, 5, 6, 7, 8]), array([0, 1, 2, 3, 4]))

또 신기한 친구를 발견
np.intersect1d라는 친구인데, 공통의 원소의 인덱스, 값을 구할 수 있다.

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

[ Numpy 100제 ] 41 ~ 50 번  (0) 2022.01.30
[ Numpy 100제 ] 31~40 번  (0) 2022.01.30
[ Numpy 100제 ] 11 ~ 20 번  (0) 2021.10.02
[ Numpy 100제 ] 01 ~ 10 번  (0) 2021.10.01

관련글 더보기

댓글 영역