본문 바로가기

Minding's Programming/Numpy & Pandas

[Numpy exercise 100] 1번 ~ 30번 문제풀이

728x90
반응형

 

Data Scientist로의 역량 강화와 데이터 분석 분야 면접 준비를 위해 numpy를 다시 한번 복습하고자

Numpy excersise 100문제를 풀기로 마음을 먹었다.

 

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

 

100개의 문제들은 위 링크에서 볼 수 있고, ipynb 파일을 통해 해답과 힌트를 제공한다. (이런 좋은 분이 계시다니...)

문제들을 풀며 내 나름대로의 정리와 해석을 달면서 공부했다.

 

 


문제풀이

 

1. Import the numpy package under the name np (★☆☆)

import numpy as np

 

2. Print the numpy version and the configuration (★☆☆)

print(np.__version__)

>>>
1.19.5

 

3. Create a null vector of size 10 (★☆☆)

  • null vector는 zero vector를 뜻함
z = np.zeros(10)
print(z)

>>>
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]

 

4. How to find the memory size of any array (★☆☆)

  • array의 메모리 사이즈 찾는 방법
  • numpy.ndarray.nbytes를 사용해서도 간단하게 구할 수 있다.
print(z.nbytes)
print(z.size * z.itemsize)
print(np.prod(z.shape) * z.itemsize)

>>>
80
80
80

 

5. How to get the documentation of the numpy add function from the command line? (★☆☆)

  • numpy의 add function에 대한 설명문서를 불러오는 방법
!python -c "import numpy; numpy.info(numpy.add)"

>>>
add(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj])

Add arguments element-wise.

Parameters
----------
(생략)

 

6. Create a null vector of size 10 but the fifth value which is 1 (★☆☆)

  • size가 10인 null vector를 만들고 5번째 원소는 1로 만들기
z = np.zeros(10)
z[4] = 1
print(z)

>>>
[0. 0. 0. 0. 1. 0. 0. 0. 0. 0.]

 

7. Create a vector with values ranging from 10 to 49 (★☆☆)

  • 값이 10에서 49를 원소로 가지고 있는 벡터 만들기
x = np.arange(10,50)
print(x)

>>>
[10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49]

 

8. Reverse a vector (first element becomes last) (★☆☆)

  • 위 배열의 원소를 뒤집는 문제
  • 인덱스를 이용해서 해결 가능
  • np.flip()을 통해 해결 가능
# 인덱스로 해결
print(x[::-1])

# np.flip() 사용
print(np.flip(x))

>>>
[49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26
 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10]
[49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26
 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10]

 

9. Create a 3x3 matrix with values ranging from 0 to 8 (★☆☆)

  • 0부터 8을 원소로 가지는 3 x 3의 행렬을 만들어라
matrix = np.arange(0,9).reshape([3,3])
print(matrix)

>>>
[[0 1 2]
 [3 4 5]
 [6 7 8]]

 

10. Find indices of non-zero elements from [1,2,0,0,4,0] (★☆☆)

  • [1,2,0,0,4,0]에서 0이 아닌 요소의 인덱스 찾기
  • 조건에 맞는 값의 인덱스 찾아주는 np.where() 메서드 사용하여 해결
  • 리스트는 array로 바꿔주어야 함
  • np.nonzero() 메서드 사용하여 해결가능
# np.where() 사용
f = np.array([1,2,0,0,4,0])
np.where(f != 0)

# np.nonzero() 사용
np.nonzero(f)

>>>
(array([0, 1, 4], dtype=int64),)

 

11. Create a 3x3 identity matrix (★☆☆)

  • 3 x 3의 항등행렬을 만들어라
  • np.identity() 메서드와 np.eye() 메서드로 만들 수 있음
  • identity()는 정방단위행렬(N x N), eye()는 대각행렬 (N x M 가능)
# np.identity() 사용
np.identity(3)

# np.eye() 사용
np.eye(3)

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

 

12. Create a 3x3x3 array with random values (★☆☆)

  • 무작위 원소를 가진 3x3x3의 array를 만들어라
  • np.random.random() 이용하여 무작위 원소 적용
rand = np.random.random([3,3,3])
rand

>>>
array([[[0.92842722, 0.92574424, 0.07725618],
        [0.75726719, 0.75362092, 0.22836732],
        [0.12551308, 0.9106576 , 0.17518133]],

       [[0.06029213, 0.99286814, 0.80926844],
        [0.42243376, 0.95335137, 0.18474632],
        [0.04488715, 0.89688706, 0.37775391]],

       [[0.94077574, 0.91818125, 0.35818829],
        [0.76793943, 0.12810186, 0.99508023],
        [0.4833759 , 0.59272653, 0.01835418]]])

 

13. Create a 10x10 array with random values and find the minimum and maximum values (★☆☆)

  • 10x10의 무작위 원소를 가진 array를 만들고 최솟값과 최댓값을 찾아라.
  • max()와 min()사용
rand = np.random.random([10,10])
print(rand.max())
print(rand.min())

>>>
0.9991753105525707
0.0009901146637728564

 

14. Create a random vector of size 30 and find the mean value (★☆☆)

  • size가 30인 무작위 벡터를 만들고 평균값을 구하라
  • mean() 사용
rand = np.random.random(30)
print(rand.mean())

 

15. Create a 2d array with 1 on the border and 0 inside (★☆☆)

  • 테두리의 원소가 1이고 안쪽 원소가 0인 2차원 배열을 만들어라
  • 1로 채워진 배열 만들고 인덱스 활용해 안쪽을 0으로 채움
arr = np.ones((3,5))
arr

>>>
array([[1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1.]])
arr[1,1:4] = 0
arr

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

 

16. How to add a border (filled with 0's) around an existing array? (★☆☆)

  • 기존 배열에 (0으로 채워진) 새로운 테두리를 추가하는 방법은?
  • np.pad()로 채울 수 있음
  • 팬시 인덱싱으로도 해결가능하다.
Z = np.ones((5,5))
Z = np.pad(Z, pad_width=1, mode='constant', constant_values=0)
print(Z)

# Using fancy indexing
Z[:, [0, -1]] = 0
Z[[0, -1], :] = 0
print(Z)

>>>
[[0. 0. 0. 0. 0. 0. 0.]
 [0. 1. 1. 1. 1. 1. 0.]
 [0. 1. 1. 1. 1. 1. 0.]
 [0. 1. 1. 1. 1. 1. 0.]
 [0. 1. 1. 1. 1. 1. 0.]
 [0. 1. 1. 1. 1. 1. 0.]
 [0. 0. 0. 0. 0. 0. 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
  1. nan
  2. False
  3. False
  4. nan
  5. True
  6. False

1~4 : nan은 '정의되지 않은 수'이기 때문에 비교하거나 연산할 수 없다.

5 : np.nan은 np.nan의 집합 내에 속한다.

6 : 3.0 * 0.1은 0.3으로 나오지 않고 0.300000000004로 출력된다. 이는 부동소수점에 의한 오차를 나타낸다.

(6번 설명출처: https://leechamin.tistory.com/31 [참신러닝 (Fresh-Learning)])

 

 

18. Create a 5x5 matrix with values 1,2,3,4 just below the diagonal (★☆☆)

  • 대각선 바로 아래에 값 1,2,3,4가 있는 5x5 행렬 만들기
  • np.diag()은 주어진 원소로 대각행렬을 만들어줌. k를 기준으로 대각선 아래/위에 삽입 가능
np.diag([1,2,3,4], k=-1)

>>>
array([[0, 0, 0, 0, 0],
       [1, 0, 0, 0, 0],
       [0, 2, 0, 0, 0],
       [0, 0, 3, 0, 0],
       [0, 0, 0, 4, 0]])

 

19. Create a 8x8 matrix and fill it with a checkerboard pattern (★☆☆)

  • 8x8 매트릭스를 만들고 체커보드 패턴으로 채웁니다.
  • 팬시인덱싱을 이용해 해결
  • [A::B]는 A부터 B의 step만큼 건너뛰며 slicing 한다는 뜻
  • np.tile로도 해결가능
# 팬시인덱싱 사용
matrix = np.zeros((8,8))
matrix[::2, 1::2] = 1
matrix[1::2, ::2] = 1
print(matrix)

# np.tile() 사용
matrix = np.tile(np.array([[0, 1], [1, 0]]), (4, 4))
print(matrix)

>>>
[[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.]]
 
 [[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]] # np.tile() 사용하면 정수로 나온다.

 

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

  • (6,7,8) 모양 배열을 고려하면 100 번째 요소의 인덱스 (x, y, z)는 무엇입니까?
  • np.unravel_index : 플랫 인덱스 또는 플랫 인덱스 배열을 튜플 좌표 배열로 변환합니다.
z = np.unravel_index(99,(6,7,8)) #100번째 인덱스 = 99
print(z)

>>>
(1, 5, 3)

 

21. Create a checkerboard 8x8 matrix using the tile function (★☆☆)

  • 타일 함수를 사용하여 체커보드 8x8 매트릭스 만들기
matrix = np.tile(np.array([[0, 1], [1, 0]]), (4, 4))
print(matrix)

>>>
[[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]]

 

22. Normalize a 5x5 random matrix (★☆☆)

  • 5x5 랜덤 행렬 정규화
  • Z = (X – 평균) / (표준편차) (Z-score nomarlization)
rand = np.random.random((5,5))
norm = (rand - rand.mean())/rand.std()
print(norm)

>>>
[[ 1.4755198  -1.18436877 -1.15214335  1.60875073 -0.01677941]
 [-0.91157011 -0.53974214 -0.76255593 -0.37546198 -0.67763248]
 [ 1.66806845  1.19832749 -0.67279504  1.07368752  0.18071735]
 [ 1.22837962 -0.52696318 -0.65502861 -1.23114673 -0.69306837]
 [-0.98135635 -1.00695036  0.68384938  0.9001969   1.37006556]]

 

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

  • 색상을 4개의 부호 없는 바이트(RGBA)로 설명하는 사용자 지정 dtype 만들기
  • data type의 축약형 중 u는 부호없는 정수로, 각각의 색깔에 해당됨
color = np.dtype([("r", np.ubyte),
                  ("g", np.ubyte),
                  ("b", np.ubyte),
                  ("a", np.ubyte)])
                  
color

>>>
dtype([('r', 'u1'), ('g', 'u1'), ('b', 'u1'), ('a', 'u1')])

 

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

  • 5x3 행렬에 3x2 행렬(실제 행렬 곱)을 곱합니다.
  • np.dot() 또는 @연산자 사용
arr1 = np.random.random((5,3))
arr2 = np.random.random((3,2))
np.dot(arr1, arr2)

# 또는
arr1@arr2

>>>
array([[0.38825541, 0.28442516],
       [0.39528622, 0.14339797],
       [1.10552462, 0.34293362],
       [0.93457422, 0.42392023],
       [0.32585785, 0.1383503 ]])

 

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

  • 1차원 배열에서 3에서 8사이 값을 음수화하여라
z = np.arange(11)
z[(2<z) & (z<9)] *= -1
z

>>>
array([ 0,  1,  2, -3, -4, -5, -6, -7, -8,  9, 10])

 

26. What is the output of the following script? (★☆☆)

  • 다음 스크립트의 출력은 어떻게 됩니까?
# Author: Jake VanderPlas

print(sum(range(5),-1))
from numpy import *
print(sum(range(5),-1))
print(sum(range(5),-1))
from numpy import *
print(sum(range(5),-1))

>>>
9
10

 

27. Consider an integer vector Z, which of these expressions are legal? (★☆☆)

  • 정수 벡터 Z를 생각해보십시오.이 표현식 중 어느 것이 합법적입니까?
Z**Z
2 << Z >> 2
Z <- Z
1j*Z
Z/1/1
Z<Z>Z
Z = np.arange(10)
print(Z**Z)
print(2 << Z >> 2)
print(Z <- Z)
print(1j*Z)
print(Z/1/1)
# print(Z<Z>Z) --> ilegal(에러발생)

 

28. What are the result of the following expressions? (★☆☆)

  • 다음 표현의 결과는 무엇입니까?
  • array 나누기는 불가하다. 하지만 // : 나누기 연산 후 소수점 이하의 수를 버리고, 정수 부분의 수만 구하는 것은 가능하다. (출처: https://leechamin.tistory.com/43?category=827917 [참신러닝 (Fresh-Learning)])
np.array(0) / np.array(0)
np.array(0) // np.array(0)
np.array([np.nan]).astype(int).astype(float)
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
[-2.14748365e+09]

 

29. How to round away from zero a float array ? (★☆☆)

  • 부동 배열 0에서 반올림하는 방법?
  • 절댓값(abs)으로 바꾸고 np.ceil()을 통해 올림한다. (반올림 X)
Z = np.random.uniform(-10,+10,10)
print(np.copysign(np.ceil(np.abs(Z)), Z))

>>>
[ 7.  7.  8. -9. -3.  7. -2.  5.  5. -7.]

 

30. How to find common values between two arrays? (★☆☆)

  • 두 배열 사이의 공통 값을 찾는 방법은 무엇입니까?
  • np.intersect1d()를 이용하여 공통원소 찾음
arr1 = np.random.randint(0,10,10)
arr2 = np.random.randint(0,10,10)
print(arr1)
print(arr2)
print(np.intersect1d(arr1, arr2))

>>>
[4 5 1 0 7 1 5 6 8 9]
[2 4 4 5 2 7 5 2 0 3]
[0 4 5 7]
728x90