[Python 데이터분석][pandas] [Python pandas] DataFrame의 문자열 칼럼을 숫자형으로 바꾸기 : pd.to_numeric(), DataFrame.astype() 

 

이번 포스팅에서는 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

  col_str
0 1
1 2
2 3
3 4
4 5

 

 

# check data types 

df.dtypes

col_str    object
dtype: object

 

df['col_int'] = pd.to_numeric(df['col_str'])

df

  col_str col_int
0 1 1
1 2 2
2 3 3
3 4 4
4 5 5

 

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

  col_str_1 col_str_2 col_str_3
0 1 4 7.0
1 2 5 8.1
2 3 6 9.2

 

 

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

  col_str_1 col_str_2 col_str_3 col_int_1 col_int_2
0 1 4 7.0 1 4
1 2 5 8.1 2 5
2 3 6 9.2 3 6

 

 

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

  col_str_1 col_str_2
0 1.0 4.1
1 2.0 5.5
2 3.0 6.0

 

 

df5.dtypes

col_str_1    float64
col_str_2    float64
dtype: object

 

경축! 아무것도 안하여 에스천사게임즈가 새로운 모습으로 재오픈 하였습니다.
어린이용이며, 설치가 필요없는 브라우저 게임입니다.
https://s1004games.com

 

 

 

(2-2) DataFrame 내 문자열 칼럼별로 int, float 데이터 형식 개별 지정해서 숫자형으로 변환하기

 

 

df6 = df4.astype({'col_str_1': int

                  'col_str_2': np.float})

 

df6

  col_str_1 col_str_2
0 1 4.1
1 2 5.5
2 3 6.0

 

 

 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

  col_1 col_2
0 1 aaa
1 2 bbb
2 3 ccc

 

 

df7.dtypes

col_1    object
col_2    object
dtype: object

 

 

 

* ValueError

 

 

# ValueError

df7 = df7.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 "aaa" During handling of the above exception, another exception occurred: -- 중간 생략 -- ~/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 "aaa" at position 0', 'occurred at index col_2')

 

 

 

* ValueError

 

# ValueError

df7 = df7.astype(int)

 

--------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-124-f50dad302c83> in <module>() ----> 1 df7 = df7.astype(int) -- 중간 생략 --

~/anaconda3/lib/python3.6/site-packages/pandas/core/dtypes/cast.py in astype_nansafe(arr, dtype, copy) 623 elif arr.dtype == np.object_ and np.issubdtype(dtype.type, np.integer): 624 # work around NumPy brokenness, #1987 --> 625 return lib.astype_intsafe(arr.ravel(), dtype).reshape(arr.shape) 626 627 if dtype.name in ("datetime64", "timedelta64"): pandas/_libs/lib.pyx in pandas._libs.lib.astype_intsafe() pandas/_libs/src/util.pxd in util.set_value_at_unsafe()  

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

  col_1 col_2
0 1 4
1 2 bbb
2 3 6

 

 

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

  col_1 col_2
0 1 4.0
1 2 NaN
2 3 6.0

 

 

 

많은 도움이 되었기를 바랍니다. 

출처: https://rfriend.tistory.com/470 [R, Python 분석과 프로그래밍의 친구 (by R Friend):티스토리]

 

 

 

 

 

본 웹사이트는 광고를 포함하고 있습니다.
광고 클릭에서 발생하는 수익금은 모두 웹사이트 서버의 유지 및 관리, 그리고 기술 콘텐츠 향상을 위해 쓰여집니다.
대표 김성준 주소 : 경기 용인 분당수지 U타워 등록번호 : 142-07-27414
통신판매업 신고 : 제2012-용인수지-0185호 출판업 신고 : 수지구청 제 123호 개인정보보호최고책임자 : 김성준 sjkim70@stechstar.com
대표전화 : 010-4589-2193 [fax] 02-6280-1294 COPYRIGHT(C) stechstar.com ALL RIGHTS RESERVED