작성자: admin 작성일시: 2016-07-11 21:02:49 조회수: 1492 다운로드: 95
카테고리: Python 태그목록:

Pandas 인덱스 조작

데이터프레임 인덱스 설정 및 제거

때로는 데이터프레임에 인덱스로 들어가 있어야 할 데이터가 일반 데이터 열에 들어가 있거나 반대로 일반 데이터 열이어야 할 것이 인덱스로 되어 있을 수 있다. 이 때는 set_index 명령이나 reset_index 명령으로 인덱스와 일반 데이터 열을 교환할 수 있다.

  • set_index : 기존의 행 인덱스를 제거하고 데이터 열 중 하나를 인덱스로 설정
  • reset_index : 기존의 행 인덱스를 제거하고 인덱스를 마지막 데이터 열로 추가
In:
np.random.seed(0)
df = pd.DataFrame(np.random.randint(1, 10, (10, 4)), 
                  columns=["C1", "C2", "C3", "C4"])
df
Out:
C1 C2 C3 C4
0 6 1 4 4
1 8 4 6 3
2 5 8 7 9
3 9 2 7 8
4 8 9 2 6
5 9 5 4 1
6 4 6 1 3
7 4 9 2 4
8 4 4 8 1
9 2 1 5 8

set_index 명령으로 C1을 인덱스로 설정할 수 있다. 이 때 기존 인덱스는 없어진다.

In:
df1 = df.set_index("C1")
df1
Out:
C2 C3 C4
C1
6 1 4 4
8 4 6 3
5 8 7 9
9 2 7 8
8 9 2 6
9 5 4 1
4 6 1 3
4 9 2 4
4 4 8 1
2 1 5 8

마찬가지로 C2 열을 인덱스로 지정하면 기존의 인덱스는 사라진다.

In:
df2 = df1.set_index("C2")
df2
Out:
C3 C4
C2
1 4 4
4 6 3
8 7 9
2 7 8
9 2 6
5 4 1
6 1 3
9 2 4
4 8 1
1 5 8

reset_index 명령으로 인덱스 열을 보통의 자료열로 넣을 수 있다. 이 때 인덱스 열은 자료열의 가장 선두로 삽입된다. 인덱스는 숫자로 된 디폴트 인덱스가 된다.

In:
df1.reset_index()
Out:
C1 C2 C3 C4
0 6 1 4 4
1 8 4 6 3
2 5 8 7 9
3 9 2 7 8
4 8 9 2 6
5 9 5 4 1
6 4 6 1 3
7 4 9 2 4
8 4 4 8 1
9 2 1 5 8

reset_index 명령 사용시에 drop=True 로 설정하면 인덱스 열을 보통의 자료열로 올리는 것이 아니라 그냥 버리게 된다.

In:
df1.reset_index(drop=True)
Out:
C2 C3 C4
0 1 4 4
1 4 6 3
2 8 7 9
3 2 7 8
4 9 2 6
5 5 4 1
6 6 1 3
7 9 2 4
8 4 8 1
9 1 5 8

연습 문제 1

5명의 학생의 국어, 영어, 수학 점수를 나타내는 데이터프레임 df_score 을 다음과 같이 만든다.

  1. 데이터프레임 df_score 생성시에 학생 이름을 나타내는 열이 일반 데이터 열이 되도록 만든 후에 set_index 명령으로 인덱스로 변경한다.
  2. 학생 이름을 나타내는 열을 포함시키지 않고 데이터프레임 df_score 을 생성한 후, df_score.index 속성에 학생 이름을 나타내는 열을 지정하여 인덱스를 지정한다. 그 다음 reset_index 명령으로 이 인덱스 열을 일반 데이터 열로 만든다.

다중 인덱스

행이나 열 각각에 여러 계층의 복수 인덱스 즉, 다중 인덱스를 설정할 수도 있다.

데이터프레임을 생성할 때 columns 인수에 리스트의 리스트(행렬) 형태로 인덱스를 넣으면 다중 열 인덱스를 가진다.

In:
np.random.seed(0)
df3 = pd.DataFrame(np.random.randint(1, 10, (10, 4)), 
                  columns=[["A", "A", "B", "B"], ["C1", "C2", "C3", "C4"]])
df3
Out:
A B
C1 C2 C3 C4
0 6 1 4 4
1 8 4 6 3
2 5 8 7 9
3 9 2 7 8
4 8 9 2 6
5 9 5 4 1
6 4 6 1 3
7 4 9 2 4
8 4 4 8 1
9 2 1 5 8

다중 인덱스는 이름을 지정하면 더 편리하게 사용할 수 있다. 열 인덱스들의 이름 지정은 columns 객체의 names 속성에 리스트를 넣어서 지정한다.

In:
df3.columns.names = ["Cdx1", "Cdx2"]
df3
Out:
Cdx1 A B
Cdx2 C1 C2 C3 C4
0 6 1 4 4
1 8 4 6 3
2 5 8 7 9
3 9 2 7 8
4 8 9 2 6
5 9 5 4 1
6 4 6 1 3
7 4 9 2 4
8 4 4 8 1
9 2 1 5 8

마찬가지로 데이터프레임을 생성할 때 index 인수에 리스트의 리스트(행렬) 형태로 인덱스를 넣으면 다중 (행) 인덱스를 가진다. 행 인덱스들의 이름 지정은 index 객체의 names 속성에 리스트를 넣어서 지정한다.

In:
np.random.seed(0)
df4 = pd.DataFrame(np.random.randint(1, 10, (8, 4)), 
                  columns=[["A", "A", "B", "B"], ["C", "D", "C", "D"]],
                  index=[["M", "M", "M", "M", "F", "F", "F", "F"], ["ID" + str(i) for i in range(4)] * 2])
df4.columns.names = ["Cdx1", "Cdx2"]
df4.index.names = ["Rdx1", "Rdx2"]
df4
Out:
Cdx1 A B
Cdx2 C D C D
Rdx1 Rdx2
M ID0 6 1 4 4
ID1 8 4 6 3
ID2 5 8 7 9
ID3 9 2 7 8
F ID0 8 9 2 6
ID1 9 5 4 1
ID2 4 6 1 3
ID3 4 9 2 4

행 인덱스와 열 인덱스 교환

행 인덱스와 열 인덱스는 stack 명령이나 unstack 명령으로 교환할 수 있다.

  • stack()

    • 열 인덱스 -> 행 인덱스로 변환
  • unstack()

    • 행 인덱스 -> 열 인덱스로 변환

stack 명령을 실행하면 열 인덱스가 시계 방향으로 90도 회전한 것과 비슷한 모양이 된다. 마찬가지로 unstack 명령을 실행하면 행 인덱스가 반시계 방향으로 90도 회전한 것과 비슷하다.

인덱스 조작시에는 이름이나 숫자 인덱스를 사용한다.

In:
df4.stack("Cdx1")
Out:
Cdx2 C D
Rdx1 Rdx2 Cdx1
M ID0 A 6 1
B 4 4
ID1 A 8 4
B 6 3
ID2 A 5 8
B 7 9
ID3 A 9 2
B 7 8
F ID0 A 8 9
B 2 6
ID1 A 9 5
B 4 1
ID2 A 4 6
B 1 3
ID3 A 4 9
B 2 4
In:
df4.stack(0)
Out:
Cdx2 C D
Rdx1 Rdx2 Cdx1
M ID0 A 6 1
B 4 4
ID1 A 8 4
B 6 3
ID2 A 5 8
B 7 9
ID3 A 9 2
B 7 8
F ID0 A 8 9
B 2 6
ID1 A 9 5
B 4 1
ID2 A 4 6
B 1 3
ID3 A 4 9
B 2 4
In:
df4.unstack("Rdx2")
Out:
Cdx1 A B
Cdx2 C D C D
Rdx2 ID0 ID1 ID2 ID3 ID0 ID1 ID2 ID3 ID0 ID1 ID2 ID3 ID0 ID1 ID2 ID3
Rdx1
F 8 9 4 4 9 5 6 9 2 4 1 2 6 1 3 4
M 6 8 5 9 1 4 8 2 4 6 7 7 4 3 9 8
In:
df4.unstack(1)
Out:
Cdx1 A B
Cdx2 C D C D
Rdx2 ID0 ID1 ID2 ID3 ID0 ID1 ID2 ID3 ID0 ID1 ID2 ID3 ID0 ID1 ID2 ID3
Rdx1
F 8 9 4 4 9 5 6 9 2 4 1 2 6 1 3 4
M 6 8 5 9 1 4 8 2 4 6 7 7 4 3 9 8

다중 인덱스가 있는 경우의 인덱싱

데이터프레임이 다중 인덱스를 가지는 경우에는 인덱스가 하나의 라벨이나 숫자가 아니라 ()로 둘러싸인 튜플이 되어야 한다. 만약 하나의 레벨 값만 넣으면 다중 인덱스 중에서 가장 상위의 값을 지정한 것으로 본다.

예를 들어 앞에서 만든 df3 데이터프레임의 경우 다음과 같이 인덱싱한다.

In:
df3
Out:
Cdx1 A B
Cdx2 C1 C2 C3 C4
0 6 1 4 4
1 8 4 6 3
2 5 8 7 9
3 9 2 7 8
4 8 9 2 6
5 9 5 4 1
6 4 6 1 3
7 4 9 2 4
8 4 4 8 1
9 2 1 5 8
In:
df3["A"]
Out:
Cdx2 C1 C2
0 6 1
1 8 4
2 5 8
3 9 2
4 8 9
5 9 5
6 4 6
7 4 9
8 4 4
9 2 1
In:
df3[("A", "C1")]
Out:
0    6
1    8
2    5
3    9
4    8
5    9
6    4
7    4
8    4
9    2
Name: (A, C1), dtype: int64
In:
df3.loc[2, ("A", "C1")]
Out:
5
In:
df3.loc[2, ("A", "C1")] = 555
In:
df3
Out:
Cdx1 A B
Cdx2 C1 C2 C3 C4
0 6 1 4 4
1 8 4 6 3
2 555 8 7 9
3 9 2 7 8
4 8 9 2 6
5 9 5 4 1
6 4 6 1 3
7 4 9 2 4
8 4 4 8 1
9 2 1 5 8

df4 데이터프레임은 다음과 같이 인덱싱할 수 있다.

In:
df4
Out:
Cdx1 A B
Cdx2 C D C D
Rdx1 Rdx2
M ID0 6 1 4 4
ID1 8 4 6 3
ID2 5 8 7 9
ID3 9 2 7 8
F ID0 8 9 2 6
ID1 9 5 4 1
ID2 4 6 1 3
ID3 4 9 2 4
In:
df4.loc[("M", "ID0"), ("A", "C")]
Out:
6
In:
df4.loc[:, ("A", "C")]
Out:
Rdx1  Rdx2
M     ID0     6
      ID1     8
      ID2     5
      ID3     9
F     ID0     8
      ID1     9
      ID2     4
      ID3     4
Name: (A, C), dtype: int64
In:
df4.loc[("M", "ID0"), :]
Out:
Cdx1  Cdx2
A     C       6
      D       1
B     C       4
      D       4
Name: (M, ID0), dtype: int64
In:
df4.loc[("All", "All"), :] = df4.sum()
In:
df4
Out:
Cdx1 A B
Cdx2 C D C D
Rdx1 Rdx2
M ID0 6.0 1.0 4.0 4.0
ID1 8.0 4.0 6.0 3.0
ID2 5.0 8.0 7.0 9.0
ID3 9.0 2.0 7.0 8.0
F ID0 8.0 9.0 2.0 6.0
ID1 9.0 5.0 4.0 1.0
ID2 4.0 6.0 1.0 3.0
ID3 4.0 9.0 2.0 4.0
All All 53.0 44.0 33.0 38.0

다중 인덱스의 인덱스 순서 교환

다중 인덱스의 인덱스 순서를 바꾸고 싶으면 swaplevel 명령을 사용한다.

  • swaplevel(i, j, axis)

ij는 교환하고자 하는 인덱스 라벨(혹은 인덱스 번호)이고 axis는 0일 때 행 인덱스, 1일 때 열 인덱스를 뜻한다.

In:
df4.swaplevel("Rdx1", "Rdx2")
Out:
Cdx1 A B
Cdx2 C D C D
Rdx2 Rdx1
ID0 M 6.0 1.0 4.0 4.0
ID1 M 8.0 4.0 6.0 3.0
ID2 M 5.0 8.0 7.0 9.0
ID3 M 9.0 2.0 7.0 8.0
ID0 F 8.0 9.0 2.0 6.0
ID1 F 9.0 5.0 4.0 1.0
ID2 F 4.0 6.0 1.0 3.0
ID3 F 4.0 9.0 2.0 4.0
All All 53.0 44.0 33.0 38.0
In:
df4.swaplevel("Cdx1", "Cdx2", 1)
Out:
Cdx2 C D C D
Cdx1 A A B B
Rdx1 Rdx2
M ID0 6.0 1.0 4.0 4.0
ID1 8.0 4.0 6.0 3.0
ID2 5.0 8.0 7.0 9.0
ID3 9.0 2.0 7.0 8.0
F ID0 8.0 9.0 2.0 6.0
ID1 9.0 5.0 4.0 1.0
ID2 4.0 6.0 1.0 3.0
ID3 4.0 9.0 2.0 4.0
All All 53.0 44.0 33.0 38.0

연습 문제 2

A 반 학생 5명과 B반 학생 5명의 국어, 영어, 수학 점수를 나타내는 데이터프레임을 다음과 같이 만든다.

  1. "반", "번호", "국어", "영어", "수학" 을 열로 가지는 데이터프레임 df_score2을 만든다.

  2. df_score2을 변형하여 1차 행 인덱스로 "반"을 2차 행 인덱스로 "번호"을 가지는 데이터프레임을 만든다.

  3. 위 데이터 프레임에 각 학생의 평균을 나타내는 행을 오른쪽에 추가한다.

  4. df_score2을 변형하여 행 인덱스로 "번호"을, 1차 열 인덱스로 "국어", "영어", "수학"을, 2차 열 인덱스로 "반"을 가지는 데이터프레임을 만든다.

  5. 위 데이터 프레임에 각 반별 각 과목의 평균을 나타내는 행을 아래에 추가한다.

질문/덧글

아직 질문이나 덧글이 없습니다. 첫번째 글을 남겨주세요!