[Python pandas] DataFrame의 문자열 칼럼을 숫자형으로 바꾸기 : pd.to_numeric(), DataFrame.astype()
Python 분석과 프로그래밍/Python 데이터 전처리 2019. 8. 25. 16:54이번 포스팅에서는 Python pandas DataFrame 이나 Series 내 문자열 칼럼을 숫자형으로 변환(how to convert string columns to numeric data types in pandas DataFrame, Series) 하는 2가지 방법을 소개하겠습니다.
(1) pd.to_numeric() 함수를 이용한 문자열 칼럼의 숫자형 변환
(2) astype() 메소드를 이용한 문자열 칼럼의 숫자형 변환
(1) pd.to_numeric() 함수를 이용한 문자열 칼럼의 숫자형 변환 |
(1-1) 한개의 문자열 칼럼을 숫자형으로 바꾸기
import numpy as np import pandas as pd # make a DataFrame df = pd.DataFrame({'col_str': ['1', '2', '3', '4', '5']}) df
# check data types df.dtypes col_str object
dtype: object df['col_int'] = pd.to_numeric(df['col_str']) df
df.dtypes col_str object
col_int int64
dtype: object |
(1-2) apply() 함수와 to_numeric() 함수를 사용해 DataFrame 내 다수의 문자열 칼럼을 숫자형으로 바꾸기
# make a DataFrame with 3 string columns df2 = pd.DataFrame({'col_str_1': ['1', '2', '3'], 'col_str_2': ['4', '5', '6'], 'col_str_3': ['7.0', '8.1', '9.2']}) df2
df2.dtypes col_str_1 object
col_str_2 object
col_str_3 object
dtype: object # convert 'col_str_1' and 'col_str_2' to numeric df2[['col_int_1', 'col_int_2']] = df2[['col_str_1', 'col_str_2']].apply(pd.to_numeric) df2
df2.dtypes col_str_1 object
col_str_2 object
col_str_3 object
col_int_1 int64
col_int_2 int64
dtype: object # convert all columns of a DataFrame to numeric using apply() and to_numeric together df3 = df2.apply(pd.to_numeric) df3.dtypes col_str_1 int64
col_str_2 int64
col_str_3 float64
col_int_1 int64
col_int_2 int64
dtype: object |
(2) astype() 메소드를 이용한 문자열 칼럼의 숫자형 변환 |
(2-1) DataFrame 내 모든 문자열 칼럼을 float로 한꺼번에 변환하기
df4 = pd.DataFrame({'col_str_1': ['1', '2', '3'], 'col_str_2': ['4.1', '5.5', '6.0']}) df4.dtypes col_str_1 object
col_str_2 object
dtype: object df5 = df4.astype(float) df5
df5.dtypes col_str_1 float64 col_str_2 float64 dtype: object |
(2-2) DataFrame 내 문자열 칼럼별로 int, float 데이터 형식 개별 지정해서 숫자형으로 변환하기
df6 = df4.astype({'col_str_1': int, 'col_str_2': np.float}) df6
df6.dtypes col_str_1 int64 col_str_2 float64 dtype: object |
DataFrame에 문자가 포함된 칼럼이 같이 있을 경우 ValueError |
물론 DataFrame 내의 문자열 중에서 숫자가 아니라 문자(character)로 이루어진 문자열(string)이 포함되어 있을 경우 apply(pd.to_numeric) 함수나 DataFrame.astype(int) 메소드를 써서 한꺼번에 숫자형 데이터 형태로 변환하려고 하면 ValueError 가 발생합니다. (너무 당연한 거라서 여기에 써야 하나 싶기도 한데요... ^^;)
이럴 때는 숫자만 들어있는 문자열 칼럼만을 선택해서 개별적으로 변환을 해주면 됩니다.
아래는 문자로만 구성된 문자열 'col_2' 를 포함한 df7 데이터프레임을 만들어서 전체 칼럼을 숫자형으로 바꾸려고 했을 때 ValueError 가 발생한 예입니다.
df7 = pd.DataFrame({'col_1': ['1', '2', '3'], 'col_2': ['aaa', 'bbb', 'ccc']}) df7
df7.dtypes col_1 object col_2 object dtype: object
|
* ValueError
# ValueError df7 = df7.apply(pd.to_numeric)
|
* ValueError
# ValueError df7 = df7.astype(int)
ValueError: invalid literal for int() with base 10: 'aaa' |
문자열을 숫자형으로 변환 시 ValueError 를 무시하기: df.apply(pd.to_numeric, errors = 'coerce') |
위의 예와는 조금 다르게 문자형을 숫자형으로 변환하려는 칼럼이 맞는데요, 값 중에 몇 개가 실수로 숫자로 된 문자열이 아니라 문자로 된 문자열이 몇 개 포함되어 있다고 해봅시다. 이럴 경우 문자열을 숫자로 파싱할 수 없다면서 ValueError가 발생하는데요, 문자가 포함되어 있는 경우는 강제로 'NaN'으 값으로 변환하고, 나머지 숫자로된 문자열은 숫자형으로 변환해주려면 errors = 'coerce' 옵션을 추가해주면 됩니다.
df8 = pd.DataFrame({'col_1': ['1', '2', '3'], 'col_2': ['4', 'bbb', '6']}) df8
df8 = df8.apply(pd.to_numeric) --------------------------------------------------------------------------- ValueError Traceback (most recent call last) pandas/_libs/src/inference.pyx in pandas._libs.lib.maybe_convert_numeric() ValueError: Unable to parse string "bbb" During handling of the above exception, another exception occurred: ValueError Traceback (most recent call last) <ipython-input-130-9e8d711c10d5> in <module>() ----> 1 df8 = df8.apply(pd.to_numeric) ~/anaconda3/lib/python3.6/site-packages/pandas/core/frame.py in apply(self, func, axis, broadcast, raw, reduce, args, **kwds) 4260 f, axis, 4261 reduce=reduce, -> 4262 ignore_failures=ignore_failures) 4263 else: 4264 return self._apply_broadcast(f, axis) ~/anaconda3/lib/python3.6/site-packages/pandas/core/frame.py in _apply_standard(self, func, axis, ignore_failures, reduce) 4356 try: 4357 for i, v in enumerate(series_gen): -> 4358 results[i] = func(v) 4359 keys.append(v.name) 4360 except Exception as e: ~/anaconda3/lib/python3.6/site-packages/pandas/core/tools/numeric.py in to_numeric(arg, errors, downcast) 124 coerce_numeric = False if errors in ('ignore', 'raise') else True 125 values = lib.maybe_convert_numeric(values, set(), --> 126 coerce_numeric=coerce_numeric) 127 128 except Exception: pandas/_libs/src/inference.pyx in pandas._libs.lib.maybe_convert_numeric() ValueError: ('Unable to parse string "bbb" at position 1', 'occurred at index col_2') df8 = df8.apply(pd.to_numeric, errors = 'coerce') df8
|
많은 도움이 되었기를 바랍니다.
이번 포스팅이 도움이 되었다면 아래의 '공감~'를 꾹 눌러주세요. :-)