Numpy로 수치계산하기 (1)
Numpy로 수치계산하기 (1)
ndarray
일반적으로 n 차원 배열을 ndarray 라고 말하며, n 차원 매트릭스다. 모든 수를 인덱스로 식별한다.
ndarray는 기본적으로 다음으로 정의된다.
- 차원수 dimensions
 - 세이프 shape
 - 스트라이드 stride
 - 데이터 타입 data type
 - 실제 데이터
 
배열에서 모든 원소는 같은 데이터 타입(homogeneously typed)을 가져야한다. 
순수 파이썬과 NumPy 계산비교
1,000,000개의 무작위 원소를 갖는 두 벡터를 만들어, NumPy의 계산속도가 순수 파이썬 코드에 비해 얼마나 더 빠르지 확인해보자.
먼저 순수 파이썬 코드로 278ms 가 소요되었다.
1 2 3 4 5 6 7 8 9 10 11 12  | >>> from random import random >>> list_1 = [random() for __ in range(1000000)] >>> list_2 = [random() for __ in range(1000000)] >>>  >>> out = [ x + y for (x, y) in zip(list_1, list_2)] >>> out[:3] [1.3094170972956407, 0.9755226623463336, 1.3935934203308324] >>> %timeit [ x + y for (x, y) in zip(list_1, list_2)] 1 loop, best of 3: 278 ms per loop  | cs | 
NumPy로 동일한 연산을 해보자. np.array() 함수는 파이썬 리스트를 ndarray로 변환한다. 약 2.76ms가 소요되어 약 100배 가까이 빠름을 확인할 수 있다.
1 2 3 4 5 6 7 8 9 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  | >>> import numpy as np >>> arr_1 = np.array(list_1) >>> arr_2 = np.array(list_2) >>>  >>> type(list_1), type(arr_1) (list, numpy.ndarray) >>> arr_1.shape (1000000,) >>> arr_1.dtype dtype('float64') >>> arr_1.ndim 1 >>> arr_1.strides (8,) >>> arr_1.dtype dtype('float64') >>> sum_arr = arr_1 + arr_2 >>> sum_arr[:3] >>> array([ 1.3094171 ,  0.97552266,  1.39359342]) >>>  >>> %timeit arr_1 + arr_2 100 loops, best of 3: 2.76 ms per loop  | cs | 
배열 생성과 로딩
np.linspace( ) 함수는 수를 공백으로 나눠 배열을 만든다.
1 2 3 4 5 6 7 8 9 10 11 12 13  | >>> import numpy as np >>>  >>> print("ones", np.ones(5)) >>> print("arange", np.arange(5)) >>> print("linspace", np.linspace(0., 1., 5)) >>> print("random", np.random.uniform(size=3)) >>> print("custom", np.array([2, 5, 3])) ('ones', array([ 1.,  1.,  1.,  1.,  1.])) ('arange', array([0, 1, 2, 3, 4])) ('linspace', array([ 0.  ,  0.25,  0.5 ,  0.75,  1.  ])) ('random', array([ 0.59753005,  0.60388531,  0.31248934])) ('custom', array([2, 5, 3]))  | cs | 
np.array( ) 는 리스트나 튜플을 NumPy 배열로 변환한다.
np.ones( ) 는 기본으로 부동소수점 수의 배열을 생성하지만,  np.arange( )는 정수 배열을 생성한다. 하지만 다음과 같이 특정 데이터 타입을 명시할 수도 있다.
1 2 3 4 5 6 7 8 9 10 11 12 13  | >>> np.array([[1, 2], [3, 4]]) array([[1, 2],        [3, 4]]) >>> np.ones(5, dtype=np.int64) array([1, 1, 1, 1, 1]) >>> np.arange(5).astype(np.float64) array([ 0.,  1.,  2.,  3.,  4.])  | cs | 
파일에서 배열 로딩
NYC 택시 데이터를 가지고 실습해보자. NYC 택시 데이터는 아래와 같은 구조를 가졌다.
- numpy.load(file, mmap_mode=None, allow_pickle=True, fix_imports=True, encoding='ASCII')
 Load arrays or pickled objects from .npy, .npz or pickled files.
- numpy.save(file, arr, allow_pickle=True, fix_imports=True)
 Save an array to a binary file in NumPy .npy format.
- numpy.fromfile(file, dtype=float, count=-1, sep='')
 Construct an array from data in a text or binary file.
- numpy.fromstring(string, dtype=float, count=-1, sep='')¶
 A new 1-D array initialized from raw binary or text data in a string.
- numpy.loadtxt(fname, dtype=<type 'float'>, comments='#', delimiter=None, converters=None, skiprows=0, usecols=None, unpack=False, ndmin=0)
 Load data from a text file.
Each row in the text file must have the same number of values.
- numpy.genfromtxt(fname, dtype=<type 'float'>, comments='#', delimiter=None, skip_header=0, skip_footer=0, converters=None, missing_values=None, filling_values=None, usecols=None, names=None, excludelist=None, deletechars=None, replace_space='_', autostrip=False, case_sensitive=True, defaultfmt='f%i', unpack=None, usemask=False, loose=True, invalid_raise=True, max_rows=None)
 Load data from a text file, with missing values handled as specified.
Each line past the first skip_header lines is split at the delimiter character, and characters following the comments character are discarded.
CSV 나 다른 종류의 혼합 데이터를 로드하기 위해서는 NumPy 보다는 판다스가 더 효율적이다. 판다스는 내부적으로 NumPy를 기반으로 하고 있기 때문에, 판다스와 NumPy 구조 간에 데이터 변환은 매우 용이하다. 다음 예제를 보자.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23  | >>> import pandas as pd >>> data = pd.read_csv('data/nyc_data.csv') >>>  >>> data.shape (846945, 14) >>> pickup = data[['pickup_longitude', 'pickup_latitude']].values >>>  >>> pickup array([[-73.955925,  40.781887],        [-74.005501,  40.745735],        [-73.969955,  40.79977 ],        ...,         [-73.993492,  40.729347],        [-73.978477,  40.772945],        [-73.987206,  40.750568]]) >>> pickup.shape (846945, 2)  | cs | 
참고 사이트
The N-dimensional array (ndarray) https://docs.scipy.org/doc/numpy/reference/arrays.ndarray.html