Contents

Pandas 그룹내에서 순서대로 인덱스 부여 - cumcount()

cumcount()를 이용해서 그룹별로 각각 번호를 매길 수 있다.

/images/logo/pandas.svg
pandas 로고
  • groupby() 한 거에 cumcount()해서 그룹내에서 각각 순서대로 번호를 매길 수 있음
  • 원래 DataFrame 모양 및 index 유지됨 (transformation)
df['per_group_index'] = df.groupby('class').cumcount() + 1


import pandas as pd

df = pd.DataFrame({
    'class': ['a', 'a', 'a', 'b', 'b', 'a'],
    # 'class_temp': list('aaabba'),  # 이렇게도 되네
})
df

class
0a
1a
2a
3b
4b
5a

위와 같은 데이터가 있다고 하자.


# cumcount() 사용. 원래 index(0~5) 유지됨
df.groupby(['class']).cumcount()
0    0
1    1
2    2
3    0
4    1
5    3
dtype: int64

groupby 한 거에다 cumcount()한 결과를 보면 Series가 나왔다. 원래 DataFrame의 index도 유지되어 있다.


# 1부터 번호 매기고 싶음
df.groupby(['class']).cumcount() + 1
0    1
1    2
2    3
3    1
4    2
5    4
dtype: int64

1부터 번호를 매기고 싶으니, 1을 더해주자.


# 실제로 df에 column 추가
df['per_group_index'] = df.groupby(['class']).cumcount() + 1
df

classper_group_index
0a1
1a2
2a3
3b1
4b2
5a4

확인해 본 코드로 실제 DataFrame에 per_group_index column을 추가했다.


# 보기 좋게 소팅
df = df.sort_values(['class', 'per_group_index'])
df

classper_group_index
0a1
1a2
2a3
5a4
3b1
4b2

필요에 따라 소팅도 해주면 끝.



{Pandas 문서} DataFrameGroupBy.cumcount 따르면, 아래 코드와 비슷한 느낌 이라고 한다.

import numpy as np

df.groupby('class').apply(lambda x: pd.Series(np.arange(len(x)) + 1, index=x.index))
class   
a      0    1
       1    2
       2    3
       5    4
b      3    1
       4    2
dtype: int32

결과 Series가 멀티인덱스라 인덱스가 달라져서 바로 대입은 안되는데, cumcount() 쓰면 되니까 그런가 부다 하자.





Related Content