繩鋸木斷水滴石穿/Python

[pandas] map과 replace의 차이

stranger95 2022. 7. 31. 11:45

판다스로 데이터프레임을 사용하면서 새로운 컬럼을 만들어야할 상황이 생겼다. 예를 들어 기존 값이 '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