-
chapter-8 판다스 자료형판다스 2021. 9. 23. 00:37In [1]:
import pandas as pd import seaborn as sns tips=sns.load_dataset("tips")
2. 여러 가지 자료형을 문자열로 변환하기¶
자료형을 변환하려면 astype 메서드를 사용하면 됩니다. 다음은 astype 메서드를 사용해 sex열의 데이터를 문자열로 변환하여 sex_str이라는 새로운 열에 저장한 것입니다.
In [2]:tips['sex_str']=tips['sex'].astype(str)
3.¶
문자열로 제대로 변환되었는지 확인해 볼까요? 자료형이 문자열인 sex_str 열이 새로 추가되었음을 알 수 있습니다.
In [3]:print(tips.dtypes)
total_bill float64 tip float64 sex category smoker category day category time category size int64 sex_str object dtype: object
4. 자료형이 변환된 데이터 다시 원래대로 만들기¶
자료형이 변환된 데이터를 다시 원래대로 만들 수 있을까요? 다음은 roral_bill 열의 자료형을 문자열로 변환한 것입니다.
In [4]:tips['total_bill']=tips['total_bill'].astype(str) print(tips.dtypes)
total_bill object tip float64 sex category smoker category day category time category size int64 sex_str object dtype: object
5.¶
과정 4에서 문자열로 변환한 total_bill 열을 다시 실수로 변환했습니다.
In [6]:tips['total_bill']=tips['total_bill'].astype(float) print(tips.dtypes)
total_bill float64 tip float64 sex category smoker category day category time category size int64 sex_str object dtype: object
잘못 입력한 데이터 처리하기¶
이번에는 잘못 입력한 데이터를 변환하는 방법에 대해 알아보겠습니다. 만약 정수가 있어야 하는 열에 문자열이 입력되어 있으면 어떻게 해야 할까요? 이런 문제를 해결하는 방법과 자료형을 변환하는 to_numeric 메서드도 함께 알아보겠습니다.
In [7]:tips_sub_miss=tips.head(10) tips_sub_miss.loc[[1,3,5,7], 'total_bill']='missing' print(tips_sub_miss)
total_bill tip sex smoker day time size sex_str 0 16.99 1.01 Female No Sun Dinner 2 Female 1 missing 1.66 Male No Sun Dinner 3 Male 2 21.01 3.50 Male No Sun Dinner 3 Male 3 missing 3.31 Male No Sun Dinner 2 Male 4 24.59 3.61 Female No Sun Dinner 4 Female 5 missing 4.71 Male No Sun Dinner 4 Male 6 8.77 2.00 Male No Sun Dinner 2 Male 7 missing 3.12 Male No Sun Dinner 4 Male 8 15.04 1.96 Male No Sun Dinner 2 Male 9 14.78 3.23 Male No Sun Dinner 2 Male
/home/dmlrkd67/anaconda3/lib/python3.8/site-packages/pandas/core/indexing.py:1720: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy self._setitem_single_column(loc, value, pi)
2.¶
데이터프레임의 자료형을 확인해 보면 total_bill열이 실수가 아니라 문자열임을 알 수 있습니다. 'missing'이라는 문자열 때문에 이런 문제가 발생한 것입니다.
In [8]:print(tips_sub_miss.dtypes)
total_bill object tip float64 sex category smoker category day category time category size int64 sex_str object dtype: object
3.¶
astype 메서드를 사용하면 이 문제를 해결할 수 있을까요? astype 메서드를 사용해 total_bill 열의 데이터를 실수로 변환하려 하면 오류가 발생합니다. 판다스는 'missing'이라는 문자열을 실수로 변환하는 방법을 모르기 때문입니다.
In [9]:tips_sub_miss['total_bill'].astype(float)
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-9-3aba35b22fb4> in <module> ----> 1 tips_sub_miss['total_bill'].astype(float) ~/anaconda3/lib/python3.8/site-packages/pandas/core/generic.py in astype(self, dtype, copy, errors) 5875 else: 5876 # else, only a single dtype is given -> 5877 new_data = self._mgr.astype(dtype=dtype, copy=copy, errors=errors) 5878 return self._constructor(new_data).__finalize__(self, method="astype") 5879 ~/anaconda3/lib/python3.8/site-packages/pandas/core/internals/managers.py in astype(self, dtype, copy, errors) 629 self, dtype, copy: bool = False, errors: str = "raise" 630 ) -> "BlockManager": --> 631 return self.apply("astype", dtype=dtype, copy=copy, errors=errors) 632 633 def convert( ~/anaconda3/lib/python3.8/site-packages/pandas/core/internals/managers.py in apply(self, f, align_keys, ignore_failures, **kwargs) 425 applied = b.apply(f, **kwargs) 426 else: --> 427 applied = getattr(b, f)(**kwargs) 428 except (TypeError, NotImplementedError): 429 if not ignore_failures: ~/anaconda3/lib/python3.8/site-packages/pandas/core/internals/blocks.py in astype(self, dtype, copy, errors) 671 vals1d = values.ravel() 672 try: --> 673 values = astype_nansafe(vals1d, dtype, copy=True) 674 except (ValueError, TypeError): 675 # e.g. astype_nansafe can fail on object-dtype of strings ~/anaconda3/lib/python3.8/site-packages/pandas/core/dtypes/cast.py in astype_nansafe(arr, dtype, copy, skipna) 1095 if copy or is_object_dtype(arr) or is_object_dtype(dtype): 1096 # Explicit copy, or required since NumPy can't view from / to object. -> 1097 return arr.astype(dtype, copy=True) 1098 1099 return arr.view(dtype) ValueError: could not convert string to float: 'missing'
4.¶
그러면 다른 방법을 사용해야 합니다. 이번에는 to_numeric 메서드를 사용해 보겠습니다. 그런데 to_numeric 메서드를 사용해도 비슷한 오류가 발생합니다.
In [10]:pd.to_numeric(tips_sub_miss['total_bill'])
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) pandas/_libs/lib.pyx in pandas._libs.lib.maybe_convert_numeric() ValueError: Unable to parse string "missing" During handling of the above exception, another exception occurred: ValueError Traceback (most recent call last) <ipython-input-10-4fcf9a4ed513> in <module> ----> 1 pd.to_numeric(tips_sub_miss['total_bill']) ~/anaconda3/lib/python3.8/site-packages/pandas/core/tools/numeric.py in to_numeric(arg, errors, downcast) 152 coerce_numeric = errors not in ("ignore", "raise") 153 try: --> 154 values = lib.maybe_convert_numeric( 155 values, set(), coerce_numeric=coerce_numeric 156 ) pandas/_libs/lib.pyx in pandas._libs.lib.maybe_convert_numeric() ValueError: Unable to parse string "missing" at position 1
5.¶
사실 to_numeric 메서드를 사용해도 문자열을 실수로 변환할 수 없습니다. 하지만 to_numeric 메서드는 errors 인자에 raise, coerce, ignore를 지정하여 오류를 어느 정도 제어 할 수 있습니다. 예를 들어 errors 인자를 raise로 설정하면 숫자로 변환할 수 없는 값이 있을 때만 오류가 발생합니다. 이런 오류는 분석가가 의도한 오류이므로 오류가 발생한 지점을 정확히 알 수 있어 유욘한 오류죠. errors 인자에 설정할 수 있는 값은 다음과 같습니다.
errors 인자에 설정할 수 있는값¶
- reise : 숫자로 변환할 수 없는 값이 있으면 오류 발생
- coerce : 숫자로 변환할 수 없는 값을 누락값으로 지정
- ignore : 아무 작업도 하지 않음
6.¶
errors 인자를 ignore로 설정하면 오류가 발생하지 않지만 자료형도 변하지 않습니다. 말 그대로 오류를 무시하는 것이죠. 여전히 total_bill은 문자열입니다.
In [13]:tips_sub_miss['total_bill']=pd.to_numeric(tips_sub_miss['total_bill'],errors='ignore') print(tips_sub_miss.dtypes)
total_bill object tip float64 sex category smoker category day category time category size int64 sex_str object dtype: object
<ipython-input-13-79f949846a95>:1: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy tips_sub_miss['total_bill']=pd.to_numeric(tips_sub_miss['total_bill'],errors='ignore')
7.¶
이번에는 errors 인자를 coerce로 설정해 보겠습니다. 그러면 'missing'이 누락값으로 바뀝니다. dtypes로 데이터프레임의 자료형을 확인해 볼까요? total_bill의 자료형이 실수로 바뀌었습니다.
In [14]:tips_sub_miss['total_bill']=pd.to_numeric(tips_sub_miss['total_bill'],errors='coerce') print(tips_sub_miss.dtypes)
total_bill float64 tip float64 sex category smoker category day category time category size int64 sex_str object dtype: object
<ipython-input-14-060d617b0158>:1: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy tips_sub_miss['total_bill']=pd.to_numeric(tips_sub_miss['total_bill'],errors='coerce')
8.¶
to_numeric 메서드에는 errors 인자 외에도 downcast 인자가 있습니다. downcast는 정수, 실수와 같은 자료형을 더 작은 형태로 만들 때 사용합니다. 이를 다운캐스트라고 하죠. downcast 인자에는 interger, unsignedm float등의 값을 사용할 수 있습니다. 다음은 total_bill 열을 다운캐스트한 것입니다. 그러면 total_bill 열의 자료형이 float64에서 float32로 바뀐 것을 알 수 있습니다. float64는 float32보다 더 많은 범위의 실수를 표현할 수 있지만 메모리 공간을 2배나 차지합니다. 만약 저장하는 실수의 예상 범위가 크지 않다면 다운캐스트하는 것이 좋습니다.
In [15]:tips_sub_miss['total_bill']= pd.to_numeric(tips_sub_miss['total_bill'],errors='coerce', downcast='float') print(tips_sub_miss.dtypes)
total_bill float32 tip float64 sex category smoker category day category time category size int64 sex_str object dtype: object
<ipython-input-15-f2dce6a42a1d>:1: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy tips_sub_miss['total_bill']= pd.to_numeric(tips_sub_miss['total_bill'],errors='coerce', downcast='float')
08-2 카테고리 자료형¶
판다스 라이브러리는 유한한 범위의 값만을 가질 수 있는 카테고리라는 특수한 자료형이 있습니다. 만약 10종류의 과일 이름을 저장한 열이 있다고 가정할 경우 문자열 자료형보다 카테고리 자료형을 사용하는 것이 용량과 속도 면에서 더 효율적입니다. 카테고리 자료형의 장점과 특징은 다음과 같습니다.
카테고리 자료형의 장점과 특징¶
- 용량과 속도 면에서 매우 효율적입니다.
- 주로 동일한 문자열이 반복되어 데이터를 구성하는 경우에 사용합니다.
In [16]:tips['sex']=tips['sex'].astype('str') print(tips.info())
<class 'pandas.core.frame.DataFrame'> RangeIndex: 244 entries, 0 to 243 Data columns (total 8 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 total_bill 244 non-null float64 1 tip 244 non-null float64 2 sex 244 non-null object 3 smoker 244 non-null category 4 day 244 non-null category 5 time 244 non-null category 6 size 244 non-null int64 7 sex_str 244 non-null object dtypes: category(3), float64(2), int64(1), object(2) memory usage: 10.8+ KB None
2.¶
다시 sex 열을 카테고리로 변환해 볼까요? info 메서드로 데이터프레임의 용량을 확인해보면 데이터프레임의 용량이 10.7+KB에서 9.1+KB로 줄어든 것을 알 수 있습니다. 이와 같이 반복되는 문자열로 구성된 데이터는 카테고리를 사용하는 것이 더 효율적입니다.
In [17]:tips['sex']=tips['sex'].astype('category') print(tips.info())
<class 'pandas.core.frame.DataFrame'> RangeIndex: 244 entries, 0 to 243 Data columns (total 8 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 total_bill 244 non-null float64 1 tip 244 non-null float64 2 sex 244 non-null category 3 smoker 244 non-null category 4 day 244 non-null category 5 time 244 non-null category 6 size 244 non-null int64 7 sex_str 244 non-null object dtypes: category(4), float64(2), int64(1), object(1) memory usage: 9.3+ KB None
마무리하며¶
이 장에서는 자료형을 다루는 방법에 대해 알아보았습니다. 특히 카테고리라는 자료형은 따로 설명했습니다. 카테고리는 데이터의 크기가 커지면 커질수록 진가를 발휘하는 자료형이기 때문에 반드시 알아두어야 합니다.
출처 : "do it 데이터 분석을 위한 판다스입문"
'판다스' 카테고리의 다른 글
chapter-10 apply 메서드 활용 (0) 2021.09.23 chapter-9 문자열 처리하기 (0) 2021.09.23 chapter-7 깔끔한 데이터 (0) 2021.09.23 chapter-6 누락값 처리하기 (0) 2021.09.23 chapter-03 판다스 데이터프레임과 시리즈 (0) 2021.09.17