데이터프레임 전처리를 하다 보면, 가끔 아래처럼 grade별로 number가 list로 묶여있는 데이터를 마주하게 된다.
data = {'grade': [1, 2, 3],
'number': [[10, 20], [30], [40, 50, 60]]}
df = pd.DataFrame(data)
###
grade number
0 1 [10, 20]
1 2 [30]
2 3 [40, 50, 60]
###
이런 경험이 없으면, long form으로 쫙 펼쳐서 보고 싶은데 참 난감하다.
이 경우 pandas에서는 어떻게 쉽게 해결할 수 있는지, 그리고 그것을 구현해 보는 시간을 갖도록 한다.
(직접 해보는 이유는, 단순히 method 하나 들고와서 "띡" 해결하는 것이 아닌 처리 로직을 이해하기 위함이다.)
1. explode 사용
pandas는 참 편리한 도구다. 잘 만들어진 explode 메소드를 사용해서 쉽게 이 난관을 해결할 수 있다.
explode() 메소드는 pandas DataFrame에서 리스트 또는 튜플로 저장된 값을 개별 행으로 분리하는 기능을 한다.
explode는 "폭발하다", "폭발적인 증가"와 같은 것들이 사전 의미인데, list elements가 폭발적으로 쫙 펴지는 느낌이라고 이해했다 ㅎ
df_exploded = df.explode('number')
df_exploded
###
grade number
0 1 10
0 1 20
1 2 30
2 3 40
2 3 50
2 3 60
###
아래와 같은 상황에서 매우 빛을 발할 것으로 생각한다.
JSON 데이터에서 리스트 값을 개별 행으로 변환할 때
CSV 데이터에서 하나의 셀에 여러 값이 있을 때 이를 분리할 때
태그 또는 키워드 데이터가 리스트 형태로 저장된 경우 이를 개별 행으로 만들 때
2. 직접 해결하기
위 키워드를 모르면 직접 해결할 수밖에 없다.
저런 내용을 처음 마주한 파린이(python+children)라면 뭐라고 검색해 볼지 상상이나 가겠는가? 어쩔 수 없다 하고 냅다 맨 땅에 코딩하고 있을 모습이 아련하다.
한 번 파린이를 빙의해서 코딩해보자.
먼저 맨 위에 있는 df라는 것을 만들었다. grade별로 number들을 가지고 있는데, 그것을 펴는 것이 목적이다.
그럼 grade 내 number 개수만큼 grade를 생성해 주면 될 것!
아래가 그 내용이다.
df 각 행을 돌면서, grade 값에 대해 number 리스트 내 원소만큼 grade 값을 반복시켜 최종 grade_list에 담는다.
number_list는 각 grade의 list가 그대로 사용된다.
grade_list = []
number_list = []
for row, idx in df.iterrows():
grade_list.extend([idx['grade']]*len(idx['number']))
number_list.extend(idx['number'])
grade_list, number_list
###
([1, 1, 2, 3, 3, 3], [10, 20, 30, 40, 50, 60])
###
최종적으로 쫙 grade값을 number 리스트 개수만큼 복사해서 쫙 풀어준 리스트를 다시 pandas dataframe으로 만들어주면 된다.
df_exploded_custom = pd.DataFrame(zip(grade_list, number_list), columns=['grade', 'number'])
df_exploded_custom
"""
grade number
0 1 10
1 1 20
2 2 30
3 3 40
4 3 50
5 3 60
"""
심심할 때, 한 번 이런 것을 생각해 보는 경험도 나름 리마인드 하기 좋고, 나중에 어떤 상황이 와도 다르게 응용할 수 있는 능력치가 된다 ㅎ keep going!
'Python > 알고리즘' 카테고리의 다른 글
[python] 직관적으로 cumulative count 계산하기(ft. pandas, numpy) (0) | 2025.03.19 |
---|---|
python 활용 x,y coordinates 정보 요약 (0) | 2025.02.12 |