[Python NumPy] ndarray 데이터 형태 지정 및 변경 (Data Types for ndarrays)
Python 분석과 프로그래밍/Python 데이터 전처리 2017. 1. 30. 16:56이번 포스팅에서는 Python의 NumPy 모듈을 사용해서
- 데이터 형태 지정 (assign data type) :
- 데이터 형태 확인 (check data type)
- 데이터 형태 변경 (convert data type)
하는 방법을 소개하겠습니다.
다양한 데이터 형태를 자유자재로 다룰 수 있다는 점이 NumPy의 주요 강점 중의 하나이며, 데이터 전처리 단계에서 데이터 형태를 지정하거나 변경(숫자형을 문자형으로, 문자형을 숫자형으로..) 하는 일이 종종 생기므로 기본기로서 꼭 익혀두어야 하는 내용입니다. 어렵지 않으니 내용 한번 훓어보시고, 실습 한번 따라해보세요.
(1) 데이터 형태의 종류 (Data Types) |
데이터 형태(Data Type, dtype)는 크게 숫자형(nuemric)과 문자형(string)으로 나누며, 숫자형으로 된 데이터 형태에는 bool 자료형(booleans, bool), 정수형 (integers, int), 부호 없는 정수형 (unsigned integers , uint), 부동소수형 (floating point, float), 복소수형 (complex) 의 5가지가 있습니다.
NumPy 에서 각 데이터 형태를 나타내는 표기법은 아래와 같으며, 데이터 형태 표기 Type 옆에 써있는 숫자 (8, 16, 31, 64, 128 등)는 단일 값을 메모리에 저장하는데 필요한 bits 수(1 byte = 8 bits)를 의미합니다.
아래 표의 Type code는 Type을 줄여서 쓴 표기로서, Type과 똑같이 결과를 반환합니다.
구분 |
Type |
Type Code |
Example | |
숫자형 (numeric) |
bool형 (booleans) |
bool |
? |
[True, True, False, False] |
정수형 (integers) |
int8 int16 int32 int64 |
i1 i2 i4 i8 |
[-2, -1, 0, 1, 2, 3] | |
부호없는 (양수) 정수형 (unsigned integers) |
uint8 uint16 uint32 uint64 |
u1 u2 u4 u8 |
[2, 1, 0, 1, 2, 3] | |
부동소수형 (floating points) |
float16 float32 float64 |
f2 f4 f8 |
[-2.0, -1.3, 0.0, 1.9, 2.2, 3.6] | |
복수수형(실수 + 허수) (complex) |
complex64 complex128 |
c8 c16 |
(1 + 2j) | |
문자형 (character) |
문자형 (string) |
string_ |
S |
['Seoul', 'Busan', 'Incheon'] |
복소수형(complex)는 고등학교 때 배우셨을텐데요, 과학자나 수학자가 아니라면 회사에서 분석업무할 때는 거의 안쓸거 같습니다. 참고로, 수학시간에는 (1+2i) 처럼 허수를 'i'로 표기하면서 배웠을텐데요, Python에서는 (1+2j) 처럼 허수를 'j'로 표기합니다.
NumPy에서 ndarray 만들 때 데이터 형태 지정해주는 3가지 방법을 소개합니다. 저는 첫번째 방법이 눈에 잘 들어오고 이해가 잘 되어서 (비록 좀 길더라도) 주로 사용합니다.
(2) NumPy 데이터 형태 지정해주기 |
(2-1) np.array([xx, xx], dtype=np.Type)
# importing numpy module In [1]: import numpy as np
In [2]: x_float64 = np.array([1.4, 2.6, 3.0, 4.9, 5.32], dtype=np.float64)
In [3]: x_float64.dtype Out[3]: dtype('float64') In [4]: x_float64 Out[4]: array([ 1.4 , 2.6 , 3. , 4.9 , 5.32])
|
데이터 형태 확인은 object.dtype 을 사용합니다.
(2-2) np.array([xx, xx], dtype=np.'Type Code')
# (2-2) making array with shorthand type code string for float64 : dtype='f8' In [5]: x_float64_1 = np.array([1.4, 2.6, 3.0, 4.9, 5.32], dtype='f8') In [6]: x_float64_1.dtype Out[6]: dtype('float64') In [7]: x_float64_1 Out[7]: array([ 1.4 , 2.6 , 3. , 4.9 , 5.32])
|
(2-3) np.Type([xx, xx])
# (2-3) making array with data type of float64 : np.folat64() In [8]: x_float64_2 = np.float64([1.4, 2.6, 3.0, 4.9, 5.32]) In [9]: x_float64_2.dtype Out[9]: dtype('float64') In [10]: x_float64_2 Out[10]: array([ 1.4 , 2.6 , 3. , 4.9 , 5.32])
|
다음으로 데이터 변환하는 방법에 대해서 알아보겠습니다.
(3) 데이터 형태 변환 (converting data type) : object.astype(np.Type) |
(3-1) float64를 int64로 변환하기 : x_float64.astype(np.int64)
float64의 소수점 부분이 int64로 변환 이후에는 짤려나갔습니다(truncated).
astype 은 새로운 배열을 복사(copy) 한다는 점 참고하세요.
In [11]: x_float64 # original data Out[11]: array([ 1.4 , 2.6 , 3. , 4.9 , 5.32])
# object.astype(np.int64) In [12]: x_int64 = x_float64.astype(np.int64) # the decimal parts are truncated In [13]: x_int64.dtype Out[13]: dtype('int64') In [14]: x_int64 Out[14]: array([1, 2, 3, 4, 5], dtype=int64)
|
(3-2) float64를 int64로 변환하기 : np.int64(x_float64)
np.int64(object) 는 (1)번에서 소개했던 int64 만드는 방법 중의 하나였습니다.
In [15]: x_int64_2 = np.int64(x_float64) In [16]: x_int64_2.dtype Out[16]: dtype('int64') In [17]: x_int64_2 Out[17]: array([1, 2, 3, 4, 5], dtype=int64)
|
(3-3) 부동소수형(float64)를 문자열(string)로 변환하기 : x_float64.astype(np.string_)
'np.string_' 의 제일 마지막에 '_' 있다는 점 빼먹지 마세요. 실수로 '_' 를 추가한게 아니라 원래 있는거 맞습니다.
# (3-3) from float64 to string : astype(np.string_) In [18]: x_string = x_float64.astype(np.string_) In [19]: x_string.dtype Out[19]: dtype('S32') In [20]: x_string Out[20]: array([b'1.4', b'2.6', b'3.0', b'4.9', b'5.32'], dtype='|S32')
|
(3-4) 문자열(string)을 부동소수형(float64)로 변환하기 : x_string.astype(np.float64)
# (2-4) from string to float64 : astype(np.float64) In [21]: x_from_string_to_float64 = x_string.astype(np.float64) In [22]: x_from_string_to_float64 Out[22]: array([ 1.4 , 2.6 , 3. , 4.9 , 5.32])
|
(4) Python의 int와 NumPy의 int64 비교 (difference between Python's native int and NumPy's int64) |
In [23]: x_py = 12345 In [24]: x_np = np.int64(12345)
|
아래 비교의 왼쪽은 Python native int에 사용 가능한 연산자(operators)와 methods, attributes 들입니다. 그리고 오른쪽은 NumPy int64에서 사용할 수 있는 연산자(operators)와 methods, attributes 들입니다. 연산자는 큰 차이가 없지만 methods, attributes에서는 NumPy가 훨씬 많음(Python int는 8개 vs. NumPy int64는 68개, 약 8배 차이)을 알 수 있습니다. 이게 바로 NumPy가 강력하다고 하는 이유 중의 하나입니다.
In [25]: dir(x_py) Out[25]: # python's native int operators ['__abs__', '__add__', '__and__', '__bool__', '__ceil__', '__class__', '__delattr__', '__dir__', '__divmod__', '__doc__', '__eq__', '__float__', '__floor__', '__floordiv__', '__format__', '__ge__', '__getattribute__', '__getnewargs__', '__gt__', '__hash__', '__index__', '__init__', '__int__', '__invert__', '__le__', '__lshift__', '__lt__', '__mod__', '__mul__', '__ne__', '__neg__', '__new__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__round__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__',
# python's native int methods and attributes 'bit_length', 'conjugate', 'denominator', 'from_bytes', 'imag', 'numerator', 'real', 'to_bytes']
|
In [26]: dir(x_np) Out[26]: # numpy's int64 operators ['T', '__abs__', '__add__', '__and__', '__array__', '__array_interface__', '__array_priority__', '__array_struct__', '__array_wrap__', '__bool__', '__class__', '__copy__', '__deepcopy__', '__delattr__', '__dir__', '__divmod__', '__doc__', '__eq__', '__float__', '__floordiv__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__index__', '__init__', '__int__', '__invert__', '__le__', '__lshift__', '__lt__', '__mod__', '__mul__', '__ne__', '__neg__', '__new__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__round__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__xor__',
# numpy's int64 methods and attributes 'all', 'any', 'argmax', 'argmin', 'argsort', 'astype', 'base', 'byteswap', 'choose', 'clip', 'compress', 'conj', 'conjugate', 'copy', 'cumprod', 'cumsum', 'data', 'denominator', 'diagonal', 'dtype', 'dump', 'dumps', 'fill', 'flags', 'flat', 'flatten', 'getfield', 'imag', 'item', 'itemset', 'itemsize', 'max', 'mean', 'min', 'nbytes', 'ndim', 'newbyteorder', 'nonzero', 'numerator', 'prod', 'ptp', 'put', 'ravel', 'real', 'repeat', 'reshape', 'resize', 'round', 'searchsorted', 'setfield', 'setflags', 'shape', 'size', 'sort', 'squeeze', 'std', 'strides', 'sum', 'swapaxes', 'take', 'tobytes', 'tofile', 'tolist', 'tostring', 'trace', 'transpose', 'var', 'view'] |
많은 도움 되었기를 바랍니다.
이번 포스팅이 도움이 되었다면 아래의 '공감 ~♡'를 꾹 눌러주세요. ^^