[판다스 입문/판다스 자료구조] 데이터프레임

2022. 10. 14. 06:31

데이터프레임은 2차원 배열이다. 판다스의 데이터프레임 자료구조는 대표적인 통계 패키지인 R의 데이터프레임에서 유래했다고 알려져 있다.

 

그림 1-1

 

[그림 1- 1]은 여러 개의 시리즈들이 모여서 데이터프레임을 이루는 구조를 보여준다.

데이터프레임의 열은 각각 시리즈 객체이다. 시리즈를 열벡터라고 하면, 데이터프레임은 여러 개의 열벡터들이 같은 행 인덱스를 기준으로 줄지어 결합된 2차원 벡터 또는 행렬이다.

 

데이터프레임은 행과 열을 나타내기 위해 두 가지 종류의 주소를 사용한다.

[그림 1-1]과 같이 행 인덱스 열 이름으로 구분한다.

 

데이터프레임의 열은 공통의 속성을 갖는 일련의 데이터를 나타내고, 행은 개별 관측대상에 대한 다양한 속성 데이터들의 모음인 레코드(record)가 된다.

 

 

목차

1. 데이터 프레임 만들기

2. 행 인덱스/열 이름 설정

3. 행/열 삭제

4. 행 선택

5. 열 선택

6. 원소 선택

7. 열 추가

8. 행 추가

9. 원소 값 변경

10. 행, 열의 위치 바꾸기


데이터 프레임 만들기

 

데이터프레임을 만들기 위해서는 같은 길이의 1차원 배열 여러 개가 필요하다.

딕셔너리의 에 해당하는 각 리스트가 시리즈 배열로 변환되어 데이터프레임의 열이 된다.

딕셔너리의 는 각 시리즈의 이름으로 변환되어 데이터프레임의 열 이름이 된다.

예제를 통해 이해해보자.

 

# 예제 1-4

import pandas as pd

dict_data = {
    'c0': [1, 2, 3],
    'c1': [4, 5, 6],
    'c2': [7, 8, 9],
    'c3': [10, 11, 12],
    'c4': [13, 14, 15]
}

df = pd.DataFrame(dict_data)

print(type(df))
print('\n')
print(df)

데이터프레임을 만들 때는 판다스 DataFrame() 함수를 사용한다.

위 예제와 같이 여러 개의 리스트를 원소로 갖는 딕셔너리를 함수의 인자로 전달하는 방식이 주로 활용된다.

 

예제 1-4 출력 결과

 

 <예제 1-4>는 리스트 5개를 원소로 갖는 딕셔너리를 정의하고, 판다스 DataFrame() 함수의 인자로 전달하여 모두 5개의 열을 갖는 데이터프레임을 만든다.

이때 딕셔너리의 키가 열 이름(c0~c4)이 되고, 값에 해당하는 각 리스트가 데이터프레임의 열이 된다.

행 인덱스에는 정수형 위치 인덱스(0, 1, 2)가 자동 지정된다.

type() 함수로 확인해보면 반환되는 객체는 데이터프레임이다.

 

 

행 인덱스/열 이름 설정

 

데이터프레임의 구조적 특성 때문에 2차원 배열 형태의 데이터를 데이터 프레임으로 변환하기 쉽다.

2차원 배열을 DataFrame() 함수 인자로 전달하여 데이터프레임으로 변환할 때 행 인덱스와 열 이름 속성을 사용자가

직접 지정할 수도 있다.

 

# 예제 1-5(1)

import pandas as pd

df = pd.DataFrame([[15, '남', '덕영중'], [17, '여', '수리중']],
                 index=['준서', '예은'],
                 columns=['나이', '성별', '학교'])

print(df)
print('\n')
print(df.index)
print('\n')
print(df.columns)

 <예제 1-5>에서는 3개의 원소를 갖는 리스트 2개를 원소로 갖는 리스트(2차원 리스트)를 판다스 DataFrame() 함수에 전달한다.

index 옵션에 행 인덱스로 사용할 배열을 지정한다.

columns 옵션에 열 이름으로 사용할 배열을 지정한다.

 

예제 1-5(1) 출력 결과

 

실행 결과에서 리스트가 행으로 변환되는 점에 유의한다.

앞에서 딕셔너리를 이용했을 때는 리스트가 열이 된 것과 차이가 있다.

       

데이터프레임의 행 인덱스는 데이터프레임.index 속성으로 접근하고, 행 인데스 배열을 구성하는 원소와 자료형을 알 수 있다.

열 이름은 데이터프레임.columns 속성으로 접근할 수 있다.

 

데이터프레임의 앵 인덱스와 열 이름 객체를 나타내는 index columns의 속성에 새로운 배열을 할당하는 방식으로 행 인덱스와 열 이름을 변경할 수 있다.

 

# 예제 1-5(2)

df.index = ['학생1', '학생2']
df.columns = ['연령', '남녀', '소속']

print(df)
print('\n')
print(df.index)
print('\n')
print(df.columns)

예제에서 데이터프레임 df의 행 인덱스를 ['학생1', '학생2']로 변경하고,

열 이름을 ['연령', '남녀', '소속']으로 변경한다.

 

예제 1-5(2) 출력 결과

 

데이터프레임에 rename() 메소드를 적용하면 행 인덱스 또는 열 이름의 일부를 선택하여 변경할 수 있다.

단, 원본 객체를 직접 수정하는 것이 아니라 새로운 데이터프레임 객체를 반환하는 점에 유의한다.

원본 객체를 변경하려면 inplace=True 옵션을 사용한다.

 

# 예제 1-6

import pandas as pd

df = pd.DataFrame([[15, '남', '덕영중'], [17, '여', '수리중']],
                 index=['준서', '예은'],
                 columns=['나이', '성별', '학교'])

print(df)
print('\n')

df.rename(columns={'나이': '연령', '성별': '남녀', '학교': '소속'}, inplace=True)
df.rename(index={'준서': '학생1', '예은': '학생2'}, inplace=True)

print(df)

위 예제에서 rename() 메소드를 적용하여, df의 열 이름을 ['연령', '남녀', '소속']으로 변경한다.

행 인덱스는 ['학생1', '학생2']로 변경한다.

열 이름, 행 인덱스 모두 inplace옵션을 True로 설정하여 데이터프레임 원본이 변경되도록 해준다.

 

예제 1-6 출력 결과

 

 

행/열 삭제

 

데이터프레임의 행 또는 열을 삭제하는 명령으로 drop() 메소드가 있다.

행을 삭제할 때는 축(axis) 옵션으로 axis=0을 입력하거나, 별도로 입력하지 않는다.

열을 삭제할 때는 축(aixs) 옵션으로 axis=1을 입력한다.

동시에 여러 행, 열을 삭제하려면 리스트 형태로 입력한다. 

 

drop() 메소드는 기존 객체를 변경하지 않고 새로운 객체를 반환한다.

따라서 원본 객체를 직접 변경하기 위해서는 inplace=True 옵션을 추가해줘야 한다.

       

예제를 통해 먼저 행을 삭제하는 방법을 알아본다.

 

# 예제 1-7

import pandas as pd

exam_data = {'수학': [90, 80, 70],
            '영어': [98, 89, 95],
            '음악': [85, 95, 100],
            '체육': [100, 90, 90]
}

df = pd.DataFrame(exam_data, index=['서준', '우현', '인아'])
print(df)
print('\n')

df2 = df[:]
df2.drop('우현', inplace=True)
print(df2)
print('\n')

df3 = df[:]
df3.drop(['우현', '인아'], axis=0, inplace=True)
print(df3)

학생의 이름을 인덱스로 하고, 과목명을 열 이름으로 하는 데이터프레임 df를 만든다.

비교를 위해 df를 복제하여 df2와 df3을 만든다.

df2에서 이름이 '우현'인 학생의 행 데이터를 삭제한다.

df3에서 이름이 '우현', '인아'인 학생의 행 데이터를 삭제한다.

 

예제 1-7 출력 결과

 

다음 예제로는 drop() 메소드를 이용하여 열을 삭제하는 방법을 알아본다.

축 옵션을 axis=1로 설정한다.

 

# 예제 1-8

import pandas as pd

exam_data = {'수학': [90, 80, 70],
            '영어': [98, 89, 95],
            '음악': [85, 95, 100],
            '체육': [100, 90, 90]
}

df = pd.DataFrame(exam_data, index=['서준', '우현', '인아'])
print(df)
print('\n')

df4 = df.copy()
df4.drop('수학', axis=1, inplace=True)
print(df4)
print('\n')

df5 = df.copy()
df5.drop(['영어', '수학'], axis=1, inplace=True)
print(df5)

<예제 1-7>의 시험 점수 데이터를 정리한 데이터프레임 df를 다시 사용한다.

비교를 위해 df4와 df5를 만든다.

df4에서 '수학'과목의 열 데이터를 삭제한다.

df5에서 '영어', '수학'과목의 열 데이터를 삭제한다.

 

예제 1-8 출력 결과

 

 

행 선택

 

데이터프레임의 행 데이터를 선택하기 위해서는 loc iloc 인덱서를 사용한다.

인덱스 이름을 기준으로 행을 선택할 때는 loc을 이용하고,

정수형 위치 인덱스를 사용할 때는 iloc을 이용한다.

구분 loc iloc
탐색 대상 인덱스 이름 정수형 위치 인덱스
범위 지정 가능(범위의 끝 포함) 가능(범위의 끝 제외)

 

아래 예제들을 통해 loc와 iloc의 사용법을 알아본다.

 

# 예제 1-9(1)

import pandas as pd

exam_data = {'수학': [90, 80, 70],
            '영어': [98, 89, 95],
            '음악': [85, 95, 100],
            '체육': [100, 90, 90]
}

df = pd.DataFrame(exam_data, index=['서준', '우현', '인아'])
print(df)
print('\n')

label1 = df.loc['서준']
position1 = df.iloc[0]

print(label1)
print('\n')
print(position1)

앞에서 사용한 학생 3명의 과목별 점수가 저장된 데이터프레임을 계속 활용한다.

각 학생들의 과목별 점수 데이터를 행으로 추출하면 시리즈 객체가 반환된다.

 

이때 loc 인덱서를 사용하려면 '서준'이라는 인덱스 이름을 직접 입력하고,

iloc을 이용할 때는 첫 번째 정수형 위치를 나타내는 0을 입력한다.

 

 

예제 1-9(1) 출력 결과

 

# 예제 1-9(2)

label2 = df.loc[['서준', '우현']]
position2 = df.iloc[[0, 1]]

print(label2)
print('\n')
print(position2)

2개 이상의 행 인덱스를 리스트 형태로 입력하면 매칭되는 모든 행 데이터를 동시에 추출한다.

loc 인덱서는 ['서준', '우현']과 같이 인덱스 이름을 배열로 전달하고,

iloc을 이용할 때는 [0, 1]과 같이 정수형 위치를 전달한다.

 

예제 1-9(2) 출력 결과

 

# 예제 1-9(3)

label3 = df.loc['서준':'우현']
position3 = df.iloc[0:1]

print(label3)
print('\n')
print(position3)

마지막으로 슬라이싱을 통해 여러 개의 행을 동시에 선택하는 방법을 살펴본다.

loc의 경우 범위의 끝이 포함되는 반면, iloc의 경우 범위의 끝이 포함되지 않는다는 점을 유의해야한다.

 

예제 1-9(3) 출력 결과

 

 

열 선택

 

데이터프레임의 열 데이터를 1개만 선택할 때는, 대괄호 안에 열 이름을 따옴표와 함께 입력하거나

도트(.) 다음에 열 이름을 입력하는 두 가지 방식을 사용한다.

단, 두 번째 방법은 반드시 열이름이 문자열일 경우에만 가능하다.

 

먼저 데이터프레임에서 열 1개를 선택하는 방법을 살펴본다.

 

# 예제 1-10(1)

import pandas as pd

exam_data = {
    '이름': ['서준', '우현', '인아'],
    '수학': [90, 80, 70],
    '영어': [98, 89, 95],
    '음악': [85, 95, 100],
    '체육': [100, 90, 90]
}

df = pd.DataFrame(exam_data)
print(df)
print(type(df))
print('\n')

math1 = df['수학']
print(math1)
print(type(math1))
print('\n')

english = df.영어
print(english)
print(type(english))

 

예제 1-10(1) 출력 결과

대괄호 안에 열 이름을 넣는 방식으로 '수학' 점수를 시리즈 객체로 추출한다.

df.영어와 같이 도트(.) 다음에 열 이름을 입력하면 '영어' 점수 데이터를 선택하여 시리즈 객체로 추출한다.

 

# 예제 1-10(2)

music_gym = df[['음악', '체육']]
print(music_gym)
print(type(music_gym))
print('\n')

math2 = df[['수학']]
print(math2)
print(type(math2))

데이터프레임에서 2개 이상의 열을 추출하는 방법이다.

 

예제 1-10(2) 출력 결과

대괄호 안에 ['음악', '체육'] 점수를 열 이름의 리스트로 입력하면 데이터프레임이 반환된다.

df[['수학']]과 같이 2중 괄호를 사용하면 열 이름 1개를 원소로 갖는 리스트를 사용하는 경우에도 시리즈가 아닌

데이터프레임을 반환한다.

 

 

원소 선택

 

데이터프레임의 행 인덱스와 열 이름을 [행, 열] 형식의 2차원 좌표로 입력하여 원소 위치를 지정하는 방법이다.

1개 행과 여러개 열을 선택하거나 그 반대의 경우에는 시리즈 객체를 반환한다.

2개 이상의 행과 2개 이상의 열을 선택하면 데이터프레임을 반환한다.

 

# 예제 1-11(1)

import pandas as pd

exam_data = {
    '이름': ['서준', '우현', '인아'],
    '수학': [90, 80, 70],
    '영어': [98, 89, 95],
    '음악': [85, 95, 100],
    '체육': [100, 90, 90]
}

df = pd.DataFrame(exam_data)
df.set_index('이름', inplace=True)
print(df)

딕셔너리를 데이터프레임 df로 변환하고, set_index() 메소드를 적용하여 '이름' 열을 새로운 행 인덱스로 지정한다.

 

예제 1-11(1) 출력 결과

 

# 예제 1-11(2)

a = df.loc['서준', '음악']
print(a)
b = df.iloc[0, 2]
print(b)

데이터프레임 df의 원소 1개를 선택하여 출력하는 예제이다.

 

예제 1-11(2) 출력 결과

 

# 예제 1-11(3)

c = df.loc['서준', ['음악', '체육']]
print(c)
d = df.iloc[0, [2, 3]]
print(d)
e = df.loc['서준', '음악':'체육']
print(e)
f = df.iloc[0, 2:]
print(f)

데이터프레임 df의 원소 2개 이상을 선택하는 예제이다.

2개 이상의 인덱스 배열을 리스트로 입력할 수도 있고, 슬라이싱 기법을 사용할 수도 있다.

 

예제 1-11(3) 출력 결과

 

# 예제 1-11(4)

g = df.loc[['서준', '우현'], ['음악', '체육']]
print(g)
h = df.iloc[[0, 1], [2, 3]]
print(h)
i = df.loc['서준':'우현', '음악':'체육']
print(i)
j = df.iloc[0:2, 2:]
print(j)

데이터프레임의 원소를 선택할 때, 행 인덱스와 열 이름을 각각 2개 이상 선택하여 데이터프레임을 얻는 예제이다.

 

예제 1-11(4) 출력 결과

 

 

열 추가

 

DataFrame 객체['추가하려는 열 이름'] = 데이터 값

위 방법으로 데이터프레임에 열을 추가할 수 있다.

이 때 모든 행에 동일한 값(입력한 데이터 값)이 입력되는 점에 유의한다.

 

# 예제 1-12

import pandas as pd

exam_data = {
    '이름': ['서준', '우현', '인아'],
    '수학': [90, 80, 70],
    '영어': [98, 89, 95],
    '음악': [85, 95, 100],
    '체육': [100, 90, 90]
}

df = pd.DataFrame(exam_data)
print(df)
print('\n')

df['국어'] = 80
print(df)

 

예제 1-12 출력 결과

 

 

행 추가

 

DataFrame.loc['새로운 행 이름'] = 데이터 값(또는 배열)

위 방법으로 행을 추가한다.

하나의 데이터 값을 입력하면 행의 모든 원소에 같은 값이 추가된다.

배열의 형태로 데이터 값을 입력할 때는 열의 개수에 맞게 입력해야 한다.

또한, 행 벡터 자체가 배열이므로, 기존 행을 복사해서 새로운 행에 그대로 추가할 수도 있다.

 

행 인덱스를 지정할 때 기존 인덱스의 순서를 따르지 않아도 된다.

기존의 데이터프레임의 마지막 인덱스가 4라고 해서 꼭 5를 추가해야 되는건 아니라는 뜻이다.

오류는 발생하지 않는 대신 행 인덱스의 이름이 입력한 인덱스 이름이 된다.

# 예제 1-13

import pandas as pd

exam_data = {
    '이름': ['서준', '우현', '인아'],
    '수학': [90, 80, 70],
    '영어': [98, 89, 95],
    '음악': [85, 95, 100],
    '체육': [100, 90, 90]
}

df = pd.DataFrame(exam_data)
print(df)
print('\n')

df.loc[3] = 0
print(df)
print('\n')

df.loc[4] = ['동규', 90, 80, 70, 60]
print(df)
print('\n')

df.loc['행5'] = df.loc[3]
print(df)

 

예제 1-13 출력 결과

 

 

원소 값 변경

 

DataFrame 객체의 일부분 또는 원소를 선택 = 새로운 값

데이터프레임의 특정 원소를 선택하고 새로운 데이터 값을 지정해주면 원소 값이 변경된다.

 

# 예제 1-14(1)

import pandas as pd

exam_data = {
    '이름': ['서준', '우현', '인아'],
    '수학': [90, 80, 70],
    '영어': [98, 89, 95],
    '음악': [85, 95, 100],
    '체육': [100, 90, 90]
}

df = pd.DataFrame(exam_data)

df.set_index('이름', inplace=True)
print(df)
print('\n')

df.iloc[0][3] = 80
print(df)
print('\n')

df.loc['서준']['체육'] = 90
print(df)
print('\n')

df.loc['서준', '체육'] = 100
print(df)

예제 1-14(1) 출력 결과

 

# 예제 1-14(2)

df.loc['서준', ['음악', '체육']] = 50
print(df)
print('\n')

df.loc['서준', ['음악', '체육']] = 100, 50
print(df)

 

예제 1-14(2) 출력 결과

 

 

행, 열의 위치 바꾸기

 

DataFrame 객체.transpose() 또는 DataFrame 객체.T

데이터프레임의 행과 열을 서로 맞바꾸는 방법이다. 선형대수학의 전치행렬과 같은 개념.

전치의 결과로 새로운 객체를 반환한다. 즉, 원본은 바뀌지 않음.

 

# 예제 1-15

import pandas as pd

exam_data = {
    '이름': ['서준', '우현', '인아'],
    '수학': [90, 80, 70],
    '영어': [98, 89, 95],
    '음악': [85, 95, 100],
    '체육': [100, 90, 90]
}

df = pd.DataFrame(exam_data)
print(df)
print('\n')

df = df.transpose()
print(df)
print('\n')

df = df.T
print(df)

 

예제 1-15 출력 결과


파이썬 머신러닝 판다스 데이터분석
저자 : 오승환
출판 : 정보문화사
발매 : 2019.06.05

 

 

BELATED ARTICLES

more