<jupyter_start><jupyter_text>판다스 자료형 자료형 다루기 - 자료형 변환하기자료형 변환은 데이터 분석 과정에서 반드시 알아야 하는 요소중 하나이다. 예를 들어 카테고리는 문자열로 변환해야 데이터 분석을 더 수월하게 할 수 있기 때문에 자주 변환하는 자료형이다. 하지만 전화번호로 평균을 구하거나 더하는 등의 계산은 거의 하지 않는다. 오히려 문자열처럼 다루는 경우가 많다. 아래 실습을 통해 여러가지 자료형을 문자열로 변환하는 방법에 대해 알아보자.-자료형을 자유자재로 변환하기 -- astype 메서드1) 이번에 사용할 데이터 집합은 seaborn 라이브러리의 tips 데이터 집합이다.<jupyter_code>import pandas as pd
import seaborn as sns

tips = sns.load_dataset("tips")<jupyter_output><empty_output><jupyter_text>2) 여러가지 자료형을 문자열로 변환하기자료형을 변환하려면 astype 메서드를 사용하면 된다. 다음은 astype 메서드를 사용해 sex 열의 데이터를 문자열로 변환하여 sex_str이라는 새로운 열에 저장한 것이다.<jupyter_code>tips['sex_str'] = tips['sex'].astype(str)<jupyter_output><empty_output><jupyter_text>3) 문자열로 제대로 변환되었는지 확인해 보자. 자료형이 문자열인 sex_str 열이 새로 추가되었음을 볼 수 있다.<jupyter_code>print(tips.dtypes)<jupyter_output>total_bill     float64
tip            float64
sex           category
smoker        category
day           category
time          category
size             int64
sex_str         object
dtype: object<jupyter_text>4) 자료형이 변환된 데이터 다시 원래대로 만들기자료형이 변환된 데이터를 다시 원래대로 만들 수 있을까? 다음은 total_bill 열의 자료형을 문자열로 변환한 것입니다.<jupyter_code>tips['total_bill'] = tips['total_bill'].astype(str)
print(tips.dtypes)<jupyter_output>total_bill      object
tip            float64
sex           category
smoker        category
day           category
time          category
size             int64
sex_str         object
dtype: object<jupyter_text>5) 과정 4에서 문자열로 변환한 total_bill 열을 다시 실수로 변환했다.<jupyter_code>tips['total_bill'] = tips['total_bill'].astype(float)
print(tips.dtypes)<jupyter_output>total_bill     float64
tip            float64
sex           category
smoker        category
day           category
time          category
size             int64
sex_str         object
dtype: object<jupyter_text>- 잘못 입력한 데이터 처리하기이번에는 잘못 입력한 데이터를 변환하는 방법에 대해 알아 보겠습니다. 만약 정수가 있어야 하는 열에 문자열이 입력되어 있으면 어떻게 해야할까? 이런 문제를 해결하는 방법과 자료형을 변환하는 to_numeric 메서드도 함께 알아보자.-잘못 입력한 문자열 처리하기 --to_numeric 메서드1) 다음은 total_bill 열의 1,3,5,7 행의 데이터를 'missing' 으로 바꿔 변수 tips_sub_miss에 저장한 것이다.<jupyter_code>tips_sub_miss = tips.head(10)
tips_sub_miss.loc[[1,3,5,7], 'total_bill'] = 'missing'
print(tips_sub_miss)<jupyter_output>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<jupyter_text>2) 데이터프레임의 자료형을 확인해 보면 total_bill 열이 실수가 아니라 문자열임을 알 수 있다. 'missing 이라는 문자열임을 알 수 있다. 'missing' 이라는 문자열 때문에 이런 문제가 생긴 것이다.<jupyter_code>print(tips_sub_miss.dtypes)<jupyter_output>total_bill      object
tip            float64
sex           category
smoker        category
day           category
time          category
size             int64
sex_str         object
dtype: object<jupyter_text>3) astype 메서드를 사용하면 이 문제를 해결할 수 있을까? astype 메서드를 사용해 total_bill 열의 데이터를 실수로 변환하려 하면 오류가 발생한다. 판다스는 'missing'이라는 문자열을 실수로 변환하는 방법을 모르기 때문이다.<jupyter_code>tips_sub_miss['total_bill'].astype(float)<jupyter_output><empty_output><jupyter_text>4) 그러면 다른 방법을 사용해야 한다. 이번에는 to_numeric 메서드를 사용해 보자.<jupyter_code>pd.to_numeric(tips_sub_miss['total_bill'])<jupyter_output><empty_output><jupyter_text>5) 사실 to_numeric 메서드를 사용해도 문자열을 실수로 변환할 수 없다. 하지만 to_numeric 메서드는 errors 인자에 raise,coerce,ignore를 지정하여 오류를 어느 정도 제어할 수 있다. 예를 들어 errors 인자를 raise로 설정하면 숫자로 변환할 수 없는 값이 있을 때만 오류가 발생한다. 이런 오류는 분석가가 의도한 오류이므로 오류가 발생한 지점을 정확히 알 수 있어 유용한 오류이다. errors 인자에 설정할 수 있는 값은 다음과 같다.- errors 인자에 설정할 수 있는 값- raise = 숫자로 변환할 수 없는 값이 있으면 오류 발생- coerce = 숫자로 변환할 수 없는 값을 누락값으로 지정- ignore = 아무 작업도 하지 않음 6) errors 인자를 ignore로 설정하면 오류가 발생하진 않지만 자료형도 변하지 않는다. 말 그대로 오류를 무시한다. 여전히 total_bill은 문자열이다.<jupyter_code>tips_sub_miss['total_bill'] = pd.to_numeric(tips_sub_miss['total_bill'],
errors='ignore')
print(tips_sub_miss.dtypes)<jupyter_output>total_bill      object
tip            float64
sex           category
smoker        category
day           category
time          category
size             int64
sex_str         object
dtype: object<jupyter_text>7) 이번엔 errors 인자를 coerce로 설정해 보자. 그러면 'missing' 이 누락값으로 바뀐다. dtypes로 데이터프레임의 자료형을 확인해 보면 total_bill이 실수로 바뀌었다.<jupyter_code>tips_sub_miss['total_bill'] = pd.to_numeric(tips_sub_miss['total_bill'],
errors='coerce')
print(tips_sub_miss.dtypes)<jupyter_output>total_bill     float64
tip            float64
sex           category
smoker        category
day           category
time          category
size             int64
sex_str         object
dtype: object<jupyter_text>8) to_numeric 메서드에는 errors 인자 외에도 downcast 인자가 있다. downcast는 정수, 실수와 같은 자료형을 더 작은 형태로 만들 때 사용합니다. 이를 다운캐스트라고 합니다. downcast 인자에는 integer, signed, unsigned, float 등의 값을 사용할 수 있다.다음은 total_bill 열을 다운캐스트한 것이다. 그러면 total_bill 열의 자료형이 float64에서 float32로 바뀐것을 알 수 있다. float64는 float32보다 더 많은 범위의 실수를 표현할 수 있지만 메모리 공간을 2배나 차지한다. 만약 저장하는 실수의 예상 범위가 크지 않다면 다운캐스트 하는 것이 좋다.<jupyter_code>tips_sub_miss['total_bill'] = pd.to_numeric(tips_sub_miss['total_bill'],
errors='coerce', downcast='float')

print(tips_sub_miss.dtypes)<jupyter_output>total_bill     float32
tip            float64
sex           category
smoker        category
day           category
time          category
size             int64
sex_str         object
dtype: object<jupyter_text>카테고리 자료형판다스 라이브러리는 유한한 범위의 값만을 가질 수 있는 카테고리라는 특수한 자료형이 있다. 만약 10종류의 과일 이름을 저장한 열이 있다고 가정할 경우 문자열 자료형 보다 카테고리 자료형을 사용하는 것이 용량과 속도 면에서 더 효율적이다. 카테고리 자료형의 장점과 특징은 다음과 같다.- 용량과 속도 면에서 매우 효율적이다.- 주로 동일한 문자열이 반복되어 데이터를 구성하는 경우에 사용한다.-문자열을 카테고리로 변환하기1) sex 열의 데이터는 남자 또는 여자만으로 구성되있다. 그래서 카테고리 자료형으로 저장되어 있다. 만약 sex 열의 자료형을 문자열로 변환하면 어떻게 될까? sex 열의 자료형을 문자열로 변환한 다음 데이터프레임의 용량을 info 메서드로 확인하면 데이터프레임의 용량이 10.8KB 정도라는 것을 확인할 수 있다.<jupyter_code>tips['sex'] = tips['sex'].astype('str')
print(tips.info())<jupyter_output><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<jupyter_text>2) 다시 sex 열의 카테고리를 변환해 보자. info 메서드로 데이터프레임의 용량을 확인해 보면 데이터프레임의 용량이 10.8+KB 에서 9.6+KB 로 줄어든 것을 볼 수 있다. 이와 같이 반복되는 문자열로 구성된 데이터는 카테고리를 사용하는 것이 더 효율적이다.<jupyter_code>tips['sex'] = tips['sex'].astype('category')
print(tips.info())<jupyter_output><class 'pandas.core.frame.DataFrame'>
RangeIndex: 244 entries, 0 to 243
Data columns (total 9 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  
 8   ses         244 non-null    category
dtypes: category(5), float64(2), int64(1), object(1)
memory usage: 9.6+ KB
None
{'fraction_non_alphanumeric': 0.07106664934390022, 'fraction_numerical': 0.03520852280109133, 'mean_word_length': 2.56884561891516, 'pattern_counts': {'":': 0, '<': 49, '<?xml version=': 0, '>': 49, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '14', 'dir': 'jupyter-structured-clean-dedup', 'id': '440319', 'license': 'MIT', 'n_tokens_mistral': 4215, 'n_tokens_neox': 4999, 'n_words': 956, 'path': 'ch8_pandas_datatype.ipynb', 'repo_name': 'jaeyoon89/doit_pandas_study', 'size': '7697'}