# 내삽법<br>Interpolation



예를 들어 실험을 통해 얻은 두 측정값 사이의 값을 추정하고 싶을 경우, 내삽법을 시도해 볼 수 있다.<br>For instance, to guess values between two measurements, we may try interpolation.



아래의 표를 살펴보자.<br>Let's take a look at the following table.




```python
# Import NumPy and matplotlib
import pylab as py


```

## `pandas` 소개<br>About `pandas`



`pandas`는 데이터 취급과 분석을 위한 파이썬 라이브러리 가운데 하나이다.<br>`pandas` is one of python libraries to handle and analyze data.



주로 *시리즈* `Series` 또는 *데이터 프레임* `DataFrame`에 데이터를 저장하는데, 각각 파이썬의 `dict` 또는 표와 비슷하다.<br>
`pandas` mostly store data in `Series` or `DataFrame`, similar to `dict` of python or a table, respectively.



일반적으로 다음과 같이 불러들인다.<br>
In general, it is imported as follows.




```python
# Import pandas for tables
import pandas as pd


```


```python
# What is this?
py.seed()

# Parameters
a = 0.5
b = 1.5

# x array
x_array = py.arange(5+0.5)

# True values of y
y_true = a * x_array + b

# contamination
noise = py.random(x_array.shape) - 0.5

# Measurement values
y_measurement = y_true + noise

# Organize data in table form
# https://stackoverflow.com/questions35160256
df = pd.DataFrame(
    {'$x$':x_array, '$y_{true}$':y_true, '$y_{measurement}$':y_measurement}, 
    columns=['$x$', '$y_{true}$', '$y_{measurement}$'],
)

# Plot data points
ax = df.plot.line(x='$x$', y='$y_{true}$')
df.plot.scatter(x='$x$', y='$y_{measurement}$', ax=ax, label='$y_{measurement}$')

py.show()


```


```python
# Present the table
df


```

여기서 $0 \le x \le 1$ 구간의 $y$ 값을 알아보자.<br>
Let's try to figure out $y$ values in the $0 \le x \le 1$ interval.



## 선형 내삽<br>Linear interpolation



### 수식화<br>Formulation



두 점 $(x_1, y_1)$, $(x_2, y_2)$ 을 지나는 직선의 방정식을 구할 수 있다.<br>We can formulate the straight line passing two points of $(x_1, y_1)$ and $(x_2, y_2)$.




```python
# Import symbolic processor module
import sympy as sy

# Initialize printing equations
sy.init_printing()


```


```python
# Declare symbols
x = sy.symbols('x')

# Multiple symbols using `:`
x1, x2 = sy.symbols('x1:3')
y1, y2 = sy.symbols('y1:3')

# Define slope
slope = (y2 - y1) / (x2 - x1)

# Define the straight line
y_interp = slope * (x - x1) + y1

# Present the equation
y_interp


```

$x$에 관해 정리하면 다음과 같을 것이다.<br>Or we may rewrite as follows.




```python
sy.collect(sy.expand(y_interp), x, sy.factor)


```

($0 \le x \le 1$ 구간에서) 임의의 $x_i$ 에 대응되는 $y_i$ 는 다음과 같이 구할 수 있다.<br>We can find $y_i$ for an arbitrary $x_i$ (within $0 \le x \le 1$ interval) as follows.




```python
# Declared x_i as a SymPy symbol
x_i = sy.symbols('x_i')

# Prepared a dictionary containing substitution pairs
substitution_dict = {
    # "substitute x with x_i"
    x: x_i,
    x1: x_array[0],
    x2: x_array[1],
    y1: y_measurement[0],
    y2: y_measurement[1],
}

# Substitution
y_i_sy = y_interp.subs(substitution_dict)

# Result of substitution
y_i_sy


```

프로그래밍 언어 구문을 생성하는 것도 가능하다.<br>SymPy may generate expressions in programming languages.




```python
python_code = sy.python(y_interp)
print(python_code)


```


```python
c_code = sy.ccode(y_interp)
print(c_code)


```


```python
fortran_code = sy.fcode(y_interp)
print(fortran_code)


```

### 실무<br>Practice



보통 `interp()` 함수를 이용한다.<br>Usually we call `interp()` function.




```python
# x values to interpolate
x_i = py.linspace(x_array[0], x_array[-1], 50+1)

# Interpolate
y_i = py.interp(x_i, x_array, y_measurement)


```


```python
# Plot data points
ax = df.plot.line(x='$x$', y='$y_{true}$')
df.plot.scatter(x='$x$', y='$y_{measurement}$', ax=ax, label='$y_{measurement}$')

# Plot interpolation
ax.plot(x_i, y_i, '.', label='$y_{interp}$')

# Show legend table
py.legend(loc=0)

py.show()


```

### `pandas`



판다스의 데이터프레임도 간단한 내삽 기능이 있다.<br>`DataFrame` of `pandas` also has simple interpolation features.




```python
df_interp_nan = df.reindex(x_i)


```


```python
# http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.interpolate.html
df_interp = df_interp_nan.interpolate(method='linear')


```


```python
# Plot data points
ax = df.plot.line(x='$x$', y='$y_{true}$')
# Plot interpolation
df_interp.plot.scatter(x='$x$', y='$y_{measurement}$', ax=ax, label='$y_{interp}$', c='orange')
df.plot.scatter(x='$x$', y='$y_{measurement}$', ax=ax, label='$y_{measurement}$')

# Show legend table
py.legend(loc=0)

py.show()


```

다음은 $y_{measurement}$ 의 히스토그램을 그린 것이다.<br>Following shows a histogram of $y_{measurement}$.




```python
df_interp['$y_{measurement}$'].hist()


```

## 3차 스플라인 곡선<br>Cubic spline curve



[스플라인](https://en.wiktionary.org/wiki/spline)은 얇고 긴 나무자를 말한다. 부드러운 곡선을 그리기 위해 사용했었다.<br>A [spline](https://en.wiktionary.org/wiki/spline) is a ruler made of a piece of thin and long rectangular wood.  Drafters used it draw a smooth curve.



[.png/1200px-Spline_(PSF).png)](https://en.wikipedia.org/wiki/Flat_spline)



여기서 "3차"는 내삽할 때 3차 다항식을 사용한다는 의미이다.<br>
"Cubic" here means that we would interpolate using a 3rd order polynomial.



$$
y = a_0 x^3 + a_1 x^2 + a_2 x + a_3
$$



### SciPy



아래 셀에서는 3차 다항식을 이용하는 내삽기 `cubic_interp` 를 만들어서 사용한다.<br>
The following cell first instantiate a cubic interpolator `cubic_interp` and use it.




```python
# https://www.scipy-lectures.org/intro/scipy.html#interpolation-scipy-interpolate

# Import interpolation subpackage
import scipy.interpolate as sn

cubic_interp = sn.interp1d(x_array, y_measurement, kind='cubic')
y_cubic = cubic_interp(x_i)


```


```python
# Plot data points
ax = df.plot.line(x='$x$', y='$y_{true}$')
df.plot.scatter(x='$x$', y='$y_{measurement}$', ax=ax, label='$y_{measurement}$')

# Plot linear interpolation
ax.plot(x_i, y_i, '.', label='$y_{linear}$')

# Plot cubic spline curve
ax.plot(x_i, y_cubic, 'x', label='$y_{cubic}$')

# Show legend table
py.legend(loc=0)

py.show()


```

### pandas




```python
# http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.interpolate.html
df_interp = df_interp_nan.interpolate(method='cubic')


```


```python
# Plot data points
ax = df.plot.line(x='$x$', y='$y_{true}$')
# Plot interpolation
df_interp.plot.scatter(x='$x$', y='$y_{measurement}$', ax=ax, label='$y_{interp}$', c='orange')
df.plot.scatter(x='$x$', y='$y_{measurement}$', ax=ax, label='$y_{measurement}$')

# Show legend table
py.legend(loc=0)

py.show()


```

* 출력 양식 설정<br>
* Output formatting




```python
pd.set_option('display.float_format', '{:.2g}'.format)


```

* 출력 행 수 설정<br>
* Number of output lines




```python
pd.options.display.max_rows = 700


```

## 연습 문제<br>Exercises



도전 과제 1 : $0(^\circ)$ ~ $360(^\circ)$ 구간에서 10도 간격으로 $sin \theta^\circ $ 값의 표를 만드시오. 그래프로도 표시해보시오.<br>
Try this 1 : Make a table of $sin \theta^\circ$ within $0(^\circ)$ ~ $360(^\circ)$ with interval of 10 degrees. Also plot it.




```python

```

도전 과제 2 : 위 표의 값을 이용하여 1도 간격으로 $sin \theta^\circ$ 값을 추정하시오.  `py.sin()` 결과와 그래프로 비교해 보시오.<br>
Try this 2 : Estimate  $sin \theta^\circ$ values with interval of 1 degree using the values of the table above.  Compare with the result of `py.sin()` on a plot.




```python

```

## 유사 난수 발생기의 `seed`<br>`seed` of pseudorandom number generator



`py.random()` 등은 유사 난수 발생기이다.<br>Functions such as `py.random()` are pseudorandom number generators.



난수, 임의의 숫자와 비슷한 특징을 보이는 일련의 숫자열를 발생시키지만 정말로 무작위인 것은 아니다.<br>It would generate a sequence of numbers showing similar characteristics of random numbers, they are not truely random.[[wikipedia](https://en.wikipedia.org/wiki/Pseudorandom_number_generator)]



`seed`로 난수 발생을 통제할 수 있다.<br>We can control random number generation using `seed`.




```python
import pylab as py


```

다음 두 셀의 결과는 다를 것이다.<br>Following two cells would show different results.




```python
py.seed()
py.random([5,])


```


```python
py.seed()
py.random([5,])


```

다음 두 셀의 결과는 같을 것이다.<br>Following two cells would show the same results.




```python
seed = 2038011903
py.seed(seed)
py.random([5,])


```


```python
py.seed(seed)
py.random([5,])


```

## 기본 매개변수<br>Default Arguments



파이썬 함수를 정의할 때 매개변수에 기본값을 정해놓을 수 있다.<br>One may designate a default value when defining a python function.




```python
def ax_plus_b(x, a=2, b=3):

    print(f'x = {x}', end=', ')
    print(f'a = {a}', end=', ')
    print(f'b = {b}')
    
    return a * x + b


```


```python
ax_plus_b(1, 2, 3)


```


```python
ax_plus_b(1)


```


```python
ax_plus_b(1, 1)


```


```python
ax_plus_b(1, b=1)


```

## `sympy` 범위 기호 생성<br>Creating `sympy` symbols with range




```python
import sympy as sy


```


```python
# help(sy.symbols)


```


```python
sy.symbols('i:n')


```


```python
sy.symbols('z1:3')


```


```python
sy.symbols('w(:c)')


```


```python
sy.symbols('a(:2)(:2)')


```

## 참고문헌<br>References



* 맥키니 저, 김영근 역, 파이썬 라이브러리를 활용한 데이터 분석, 2판, 한빛미디어, 2019, ISBN 979-11-6224-190-5 ([코드와 데이터](https://github.com/wesm/pydata-book/)) <br>Wes McKinney, Python for Data Analysis, 2nd Ed., O'Reilly, 2017. ([Code and data](https://github.com/wesm/pydata-book/))



## Final Bell<br>마지막 종




```python
# stackoverfow.com/a/24634221
import os
os.system("printf '\a'");


```


```python

```

8b9d4d29104faba61aebc99f2536f5689d0e038c
ipynb
Jupyter Notebook
20_interpolation/00_interpolation.ipynb
kangwonlee/2009eca-nmisp-template
46a09c988c5e0c4efd493afa965d4a17d32985e8
BSD-3-Clause
20_interpolation/00_interpolation.ipynb
kangwonlee/2009eca-nmisp-template
46a09c988c5e0c4efd493afa965d4a17d32985e8
BSD-3-Clause
20_interpolation/00_interpolation.ipynb
kangwonlee/2009eca-nmisp-template
46a09c988c5e0c4efd493afa965d4a17d32985e8
BSD-3-Clause
Qwen/Qwen-72B
1. YES
2. YES