기말고사 예비 문제집


In [1]:
import numpy as np

문제 1

  1. 아래 모양의 2차원 어레이를 작성하라. 단, 항목들을 일일이 입력하는 방식은 사용할 수 없다.

    $$\left [ \begin{matrix} 1 & 6 & 11 \\ 2 & 7 & 12 \\ 3 & 8 & 13 \\ 4 & 9 & 14 \\ 5 & 10 & 15 \end{matrix} \right ] $$

2. 위 행렬에서 2번 및 4번 행만으로 구성된 새로운 2차원 어레이를 생성하라.


In [5]:
a = np.arange(1, 16).reshape(3, 5).T
a


Out[5]:
array([[ 1,  6, 11],
       [ 2,  7, 12],
       [ 3,  8, 13],
       [ 4,  9, 14],
       [ 5, 10, 15]])

In [7]:
np.arange(1, 6)[:, np.newaxis] + np.arange(0, 11, 5)


Out[7]:
array([[ 1,  6, 11],
       [ 2,  7, 12],
       [ 3,  8, 13],
       [ 4,  9, 14],
       [ 5, 10, 15]])

문제 2

어레이 a가 다음과 같다.

a = np.arange(25).reshape((5,5))

어레이 a의 각 열을 아래의 어레이 b로 나누어라.

b = np.array([1., 5, 10, 15, 20])

힌트: np.newaxis를 활용하라.


In [8]:
a = np.arange(25).reshape((5,5))
a


Out[8]:
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14],
       [15, 16, 17, 18, 19],
       [20, 21, 22, 23, 24]])

In [9]:
b = np.array([1., 5, 10, 15, 20])
b


Out[9]:
array([  1.,   5.,  10.,  15.,  20.])

In [11]:
a/b[:, np.newaxis]


Out[11]:
array([[ 0.        ,  1.        ,  2.        ,  3.        ,  4.        ],
       [ 1.        ,  1.2       ,  1.4       ,  1.6       ,  1.8       ],
       [ 1.        ,  1.1       ,  1.2       ,  1.3       ,  1.4       ],
       [ 1.        ,  1.06666667,  1.13333333,  1.2       ,  1.26666667],
       [ 1.        ,  1.05      ,  1.1       ,  1.15      ,  1.2       ]])

문제 3

먼저, 구간 [0, 1]에서 임의로 숫자를 뽑아 10 x 3 행렬 모양의 2차원 어레이를 생성하라. 생성된 어레이의 각 행에서 0.5에 가장 가까운 숫자를 확인하라.

힌트:

  • np.absnp.argsort를 이용하여 각 행별로 0.5에 가장 가깝게 위치한 숫자의 위치를 확인하라.
  • 팬시 인덱싱을 활용하여 행별로 0.5에 가장 가까운 숫자를 구할 수 있다.

In [68]:
x = np.random.rand(10,3)

In [69]:
a= np.abs(x - 0.5)

In [70]:
b = a.argsort()
b


Out[70]:
array([[1, 2, 0],
       [0, 2, 1],
       [2, 1, 0],
       [0, 1, 2],
       [0, 2, 1],
       [2, 0, 1],
       [1, 2, 0],
       [2, 0, 1],
       [0, 1, 2],
       [1, 2, 0]], dtype=int64)

In [116]:
e = b[:, 0]
f = np.tile(e[:, np.newaxis], 3)
f


Out[116]:
array([[1, 1, 1],
       [0, 0, 0],
       [2, 2, 2],
       [0, 0, 0],
       [0, 0, 0],
       [2, 2, 2],
       [1, 1, 1],
       [2, 2, 2],
       [0, 0, 0],
       [1, 1, 1]], dtype=int64)

In [117]:
x[np.arange(10), e]


Out[117]:
array([ 0.36020516,  0.11133658,  0.49648004,  0.64098838,  0.57719418,
        0.30414313,  0.62430317,  0.46098543,  0.41471423,  0.47246829])

In [108]:
g = np.tile(np.arange(3), (10,1))
g


Out[108]:
array([[0, 1, 2],
       [0, 1, 2],
       [0, 1, 2],
       [0, 1, 2],
       [0, 1, 2],
       [0, 1, 2],
       [0, 1, 2],
       [0, 1, 2],
       [0, 1, 2],
       [0, 1, 2]])

In [111]:
h = g == f
h


Out[111]:
array([[False,  True, False],
       [ True, False, False],
       [False, False,  True],
       [ True, False, False],
       [ True, False, False],
       [False, False,  True],
       [False,  True, False],
       [False, False,  True],
       [ True, False, False],
       [False,  True, False]], dtype=bool)

In [112]:
x[h]


Out[112]:
array([ 0.36020516,  0.11133658,  0.49648004,  0.64098838,  0.57719418,
        0.30414313,  0.62430317,  0.46098543,  0.41471423,  0.47246829])

In [95]:
x


Out[95]:
array([[ 0.88742684,  0.36020516,  0.29113379],
       [ 0.11133658,  0.02038471,  0.08498022],
       [ 0.97377625,  0.86067098,  0.49648004],
       [ 0.64098838,  0.17324581,  0.86791237],
       [ 0.57719418,  0.8324089 ,  0.64871386],
       [ 0.23181276,  0.86539678,  0.30414313],
       [ 0.9298002 ,  0.62430317,  0.35308927],
       [ 0.34969845,  0.04929034,  0.46098543],
       [ 0.41471423,  0.34814638,  0.86092044],
       [ 0.68473178,  0.47246829,  0.56537597]])

문제 4

아래 사이트에 가면 "Lena" 이름의 여성 사신에 대한 설명을 확인할 수 있다.

http://www.cs.cmu.edu/~chuck/lennapg/

위 사이트에서 확인되는 사진은 이미지 압축 알고리즘과 관련해서 가장 많이 사용되는 사진이다. 파이썬에서는 scipy 모듈에서 2차원 어레이 형식으로 Lena 사진 데이터를 제공한다.


In [2]:
from scipy import misc

In [3]:
import matplotlib.pylab as plt

In [4]:
%pylab inline


Populating the interactive namespace from numpy and matplotlib
WARNING: pylab import has clobbered these variables: ['plt']
`%matplotlib` prevents importing * from pylab and numpy

In [5]:
lena = misc.lena()
lena


Out[5]:
array([[162, 162, 162, ..., 170, 155, 128],
       [162, 162, 162, ..., 170, 155, 128],
       [162, 162, 162, ..., 170, 155, 128],
       ..., 
       [ 43,  43,  50, ..., 104, 100,  98],
       [ 44,  44,  55, ..., 104, 105, 108],
       [ 44,  44,  55, ..., 104, 105, 108]])
  • plt.imshow 함수를 이용하여 이미지를 확인할 수 있다.

In [43]:
plt.imshow(lena)


Out[43]:
<matplotlib.image.AxesImage at 0x17522278>
  • 위 사진은 2차원 어레이 정보를 이용하므로 정확하지 않다. 흑백 사진으로 표현하고 싶으면 다음과 같이 할 수 있다.

In [53]:
plt.imshow(lena, cmap='gray')


Out[53]:
<matplotlib.image.AxesImage at 0x181c2e48>
  • 영역선택(crop) 기능을 이용하여 특정 영역을 확대해보자. 예를 들어 모든 테두리로부터 30픽셀씩 제거해보자. 픽셀 제거는 슬라이싱을 이용한다.

In [45]:
crop_lena = lena[100:-100, 100:-100]
plt.imshow(crop_lena, cmap=plt.cm.gray)


Out[45]:
<matplotlib.image.AxesImage at 0x17e13128>

In [9]:
lena.shape


Out[9]:
(512, 512)
  • Lena의 얼굴 영역을 원으로 감싸보자. 원 바깥 부분은 검은색으로 처리한다. 목걸이 장식으로 사용할 로켓(locket) 처럼 처리하는 내용이다. 예를 들어 가운데 부분을 원으로 처리하면 아래처럼 보이게 할 수 있다.

    위 사진을 구현하는 코드를 작성하라.

    힌트:

    • 먼저, lena 어레이는 (512, 512) 모양의 2차원 어레이임을 확인한다.
    • 마스크와 팬시 인덱싱을 사용한다.
    • 512 x 512 크기의 2차원 어레이에서 특정 반지름의 원 밖을 나타내는 영역을 마스킹하는 마스크를 작성해야 한다.
    • 참고로, 반지름이 230인 원의 방정식은 다음과 같다.

        (x - center_x)**2 + (y - center_y)**2 = 230**2
    • 가로, 세로 512 x 512 크기의 격자판(grid)을 다루기 위해서는 np.ogrid 함수를 이용한다.

    • 위 격자판의 중심에서의 거리가 230 이상인 항목의 값을 0으로 처리한다.

In [9]:
x = np.arange(512)
y = np.arange(512)[:, np.newaxis]

In [10]:
mask = (x - 256)**2 + (y - 256)** 2 > 230**2

In [11]:
mask[230, 430]


Out[11]:
False

In [12]:
lena[mask]=0
plt.imshow(lena, cmap='gray')


Out[12]:
<matplotlib.image.AxesImage at 0x1086daa10>

문제 5

1900년부터 1920년까지 캐나다 북부지역에서 산토끼, 스라소니, 당근의 개체수의 변화를 조사한 데이터가 아래와 같다.


In [58]:
data = np.loadtxt('data/populations.txt')

In [59]:
data


Out[59]:
array([[  1900.,  30000.,   4000.,  48300.],
       [  1901.,  47200.,   6100.,  48200.],
       [  1902.,  70200.,   9800.,  41500.],
       [  1903.,  77400.,  35200.,  38200.],
       [  1904.,  36300.,  59400.,  40600.],
       [  1905.,  20600.,  41700.,  39800.],
       [  1906.,  18100.,  19000.,  38600.],
       [  1907.,  21400.,  13000.,  42300.],
       [  1908.,  22000.,   8300.,  44500.],
       [  1909.,  25400.,   9100.,  42100.],
       [  1910.,  27100.,   7400.,  46000.],
       [  1911.,  40300.,   8000.,  46800.],
       [  1912.,  57000.,  12300.,  43800.],
       [  1913.,  76600.,  19500.,  40900.],
       [  1914.,  52300.,  45700.,  39400.],
       [  1915.,  19500.,  51100.,  39000.],
       [  1916.,  11200.,  29700.,  36700.],
       [  1917.,   7600.,  15800.,  41800.],
       [  1918.,  14600.,   9700.,  43300.],
       [  1919.,  16200.,  10100.,  41300.],
       [  1920.,  24700.,   8600.,  47300.]])

data는 2차원 어레이이며 모양은 (21,4) 이다. 이제 전치를 이용하여 토끼, 스라소니, 당근의 21년 동안의 개체수를 담은 어레이를 아래와 같이 구할 수 있다.


In [60]:
year, hares, lynxes, carrots = data.T

연도별 개체수의 변화를 확인하기 위해 그래프를 그려본다.


In [61]:
plt.axes([0.2, 0.1, 0.5, 0.8])
plt.plot(year, hares, year, lynxes, year, carrots)
plt.legend(('Hare', 'Lynx', 'Carrot'), loc=(1.05, 0.5))


Out[61]:
<matplotlib.legend.Legend at 0x18224e80>

In [62]:
hare_grad = np.gradient(hares)
hare_grad


Out[62]:
array([ 17200.,  20100.,  15100., -16950., -28400.,  -9100.,    400.,
         1950.,   2000.,   2550.,   7450.,  14950.,  18150.,  -2350.,
       -28550., -20550.,  -5950.,   1700.,   4300.,   5050.,   8500.])
  1. 각 종별로 평균 및 표준편차를 구하라.
  2. 각 종별로 가장 적은 개체수를 보였던 연도와 두 번째로 적었던 개체수를 보였던 연도를 구하라.
  3. 토끼 개체수의 변화와 스라소니 개체수 변화 사이의 상관관계를 설명하라. np.gradient 함수와 np.corrcoef 함수를 이용하라.

In [66]:
plt.plot(year, hare_grad, year, -lynxes)


Out[66]:
[<matplotlib.lines.Line2D at 0x19e29438>,
 <matplotlib.lines.Line2D at 0x19e29668>]