오늘 할 일: 끝내주게 숨쉬기
article thumbnail

판다스로 데이터프레임을 사용하면서 새로운 컬럼을 만들어야할 상황이 생겼다. 예를 들어 기존 값이 '1'이면 '01'로 대체하는 식의 작업이 필요했다. 이미 알고 있던 지식을 총동원하여 map을 적용하면 값을 변경된 새로운 컬럼을 만들 수 있을 것이라 판단했다. 그리고 실패했다.. 이유를 알아보았다.

 

import pandas as pd
df = pd.DataFrame({'a': ['x', 'y', 'z']})
df

 

예시로 사용할 데이터 프레임으로, a 컬럼에는 x, y, z 값이 들어있다. 이 값들을 딕셔너리를 이용해 맵핑하여 새로운 값으로 전환하려고 했다. x는 xx로, y는 yy로, w는 ww로 전환하고, 만약 딕셔너리에 기존 값이 키로 존재하지 않으면, 값을 그대로 보존하기를 바랬다.

df['a_map'] =  df['a'].map({'x': 'xx', 'y': 'yy', 'w': 'ww'})
df

map을 사용하니 딕셔너리에 맵핑하지 않은 z는 NaN을 반환하였다.. z는 z로 그대로 남기를 바랬는데 map은 그 작업을 할 수 있는 메소드가 아니었다.. 뒤늦게 공식문서를 찾아보니, 키로 정의되지 않은 값은 NaN을 반환한다고 써있었다.. 

 

map 대신 사용가능한 메소드를 생각해보다가 replace가 생각났다. 마찬가지로 적용해보니 의도했던 대로 결과를 반환해주었다.

df['a_replace'] =  df['a'].replace({'x': 'xx', 'y': 'yy', 'w': 'ww'})
df

map과 다르게 replace는 딕셔너리에 키로 없었던 z를 그대로 보존하고 있다. map은 기존의 값들을 맵핑하여 변환하기 때문에, 딕셔너리에 값이 존재하지 않으면 맵핑할 수 없어 NaN을 반환한 것이고, replace는 값을 바꿔주는 용도이기 때문에, 값이 존재하지 않아도 기존 값을 그대로 유지한다는 차이가 있었다.

 

이번 실수를 통해 느낀 점은 아래와 같다.

  1. 함수 사용 전 공식 문서로 정의와 활용 예시 찾아보기
  2. 알고 있는 내용도 의심해보고 다시 찾아보기

이후에 작업할 때에는 반드시 위 두 사항을 기억하고 지켜야겠다. 뒤늦게 코드를 고치는 일이 없도록..😵

 

참고

https://pandas.pydata.org/docs/reference/api/pandas.Series.map.html

 

pandas.Series.map — pandas 1.4.3 documentation

If ‘ignore’, propagate NaN values, without passing them to the mapping correspondence.

pandas.pydata.org

https://pandas.pydata.org/docs/reference/api/pandas.Series.replace.html?highlight=replace#pandas.Series.replace 

 

pandas.Series.replace — pandas 1.4.3 documentation

Regular expressions will only substitute on strings, meaning you cannot provide, for example, a regular expression matching floating point numbers and expect the columns in your frame that have a numeric dtype to be matched. However, if those floating poin

pandas.pydata.org