2024년 3월 17일 일요일

Python의 pandas를 사용한 데이터 처리 코드 해석

 Python의 코딩 스타일이라는 것이 정해져 있진 않지만 C/C++ 기반으로 시작하여 여기까지 와버린 나로써는 JavaScript 언어의 매써드 붙여쓰기 / for 문 대신 apply() 메써드 붙여쓰기는 당황 스럽다. 어쩌겠나 적응해야지. 익숙해 질때까진 새것 발건한 것 마냥 기록 좀 남겨야 겠다.

md['genres'] = md['genres'].fillna('[]').apply(literal_eval).apply(
    lambda x: [i['name'] for i in x] if isinstance(x, list) else []

 위의 코드는 pandas의 dataframe인 md를 조작하는 코드다; 결과적으로 'genres' 항목의 내용이 dict를 내부항목으로 하는 list로 되어 있는 것을 해체해서 'name'항목으로만 되어 있는 list로 만들어 버린다. 이를 위해서 코드가 좀 돌다리를 두드리면서 실행하도록 만들어 두었다. 안전한게 좋긴하지만 코드 보기가 눈아프긴 하다.

 우선, fillna('[]')는 md['genres']인 Series의 내부항목중 Na 혹은 NaN 즉, 숫자가 아니거나 아무것도 없거나 한 곳은 '[]' 문자열(실제 내용은 빈 list)을 넣어 두고,

 그 다음에 dict를 내부항목으로 갖는 list를 가지고 작업하려고 하는데 아쉽게도 해당 내용이 Series의 문자열 형태로 되어 있어서 이 부분을 해석해서 Python의 객체로 만들어 주어야 한다. 이 작업을 해주는 것이 .apply(literal_eval)이라는 것이다.

 그리고 나서 본격적으로  Series의 내부항목 list의 내용을 구조가 복잡한 dict를 해체해서 'name'항목만 남겨 주는 혹은 내용이 없으면 빈 list로 재편한다. 이 작업을 .apply()메서드와 dict의 내용을 해체하고 빈곳은 빈 list로 대체하는 lambda 함수가 해주고 있다. 

vote_counts = md[md['vote_count'].notnull()]['vote_count'].astype('int')

 이것도 마찬가지다. dataframe인 md의 'vote_count' 컬럼의 내용중 내용이 있는 항목만 추려 혹시나 있을 누락된 항목으로 발생할 수 있는 에러를 방지 하도록 해놓았다. 

 그래서, 유효한(notnull)내용만 갖는 'vote_count' 컬럼의 내용을 마지막으로 정수형으로 변환하여 vote_count에 저장하도록 해놓았다.