[판다스 입문/판다스 자료구조] 데이터프레임
데이터프레임은 2차원 배열이다. 판다스의 데이터프레임 자료구조는 대표적인 통계 패키지인 R의 데이터프레임에서 유래했다고 알려져 있다.
[그림 1- 1]은 여러 개의 시리즈들이 모여서 데이터프레임을 이루는 구조를 보여준다.
데이터프레임의 열은 각각 시리즈 객체이다. 시리즈를 열벡터라고 하면, 데이터프레임은 여러 개의 열벡터들이 같은 행 인덱스를 기준으로 줄지어 결합된 2차원 벡터 또는 행렬이다.
데이터프레임은 행과 열을 나타내기 위해 두 가지 종류의 주소를 사용한다.
[그림 1-1]과 같이 행 인덱스와 열 이름으로 구분한다.
데이터프레임의 열은 공통의 속성을 갖는 일련의 데이터를 나타내고, 행은 개별 관측대상에 대한 다양한 속성 데이터들의 모음인 레코드(record)가 된다.
목차
1. 데이터 프레임 만들기
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>는 리스트 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 옵션에 열 이름으로 사용할 배열을 지정한다.
실행 결과에서 리스트가 행으로 변환되는 점에 유의한다.
앞에서 딕셔너리를 이용했을 때는 리스트가 열이 된 것과 차이가 있다.
데이터프레임의 행 인덱스는 데이터프레임.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']로 변경하고,
열 이름을 ['연령', '남녀', '소속']으로 변경한다.
데이터프레임에 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로 설정하여 데이터프레임 원본이 변경되도록 해준다.
행/열 삭제
데이터프레임의 행 또는 열을 삭제하는 명령으로 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에서 이름이 '우현', '인아'인 학생의 행 데이터를 삭제한다.
다음 예제로는 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에서 '영어', '수학'과목의 열 데이터를 삭제한다.
행 선택
데이터프레임의 행 데이터를 선택하기 위해서는 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(2)
label2 = df.loc[['서준', '우현']]
position2 = df.iloc[[0, 1]]
print(label2)
print('\n')
print(position2)
2개 이상의 행 인덱스를 리스트 형태로 입력하면 매칭되는 모든 행 데이터를 동시에 추출한다.
loc 인덱서는 ['서준', '우현']과 같이 인덱스 이름을 배열로 전달하고,
iloc을 이용할 때는 [0, 1]과 같이 정수형 위치를 전달한다.
# 예제 1-9(3)
label3 = df.loc['서준':'우현']
position3 = df.iloc[0:1]
print(label3)
print('\n')
print(position3)
마지막으로 슬라이싱을 통해 여러 개의 행을 동시에 선택하는 방법을 살펴본다.
loc의 경우 범위의 끝이 포함되는 반면, iloc의 경우 범위의 끝이 포함되지 않는다는 점을 유의해야한다.
열 선택
데이터프레임의 열 데이터를 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))
대괄호 안에 열 이름을 넣는 방식으로 '수학' 점수를 시리즈 객체로 추출한다.
df.영어와 같이 도트(.) 다음에 열 이름을 입력하면 '영어' 점수 데이터를 선택하여 시리즈 객체로 추출한다.
# 예제 1-10(2)
music_gym = df[['음악', '체육']]
print(music_gym)
print(type(music_gym))
print('\n')
math2 = df[['수학']]
print(math2)
print(type(math2))
데이터프레임에서 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(2)
a = df.loc['서준', '음악']
print(a)
b = df.iloc[0, 2]
print(b)
데이터프레임 df의 원소 1개를 선택하여 출력하는 예제이다.
# 예제 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(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개 이상 선택하여 데이터프레임을 얻는 예제이다.
열 추가
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)
행 추가
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)
원소 값 변경
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(2)
df.loc['서준', ['음악', '체육']] = 50
print(df)
print('\n')
df.loc['서준', ['음악', '체육']] = 100, 50
print(df)
행, 열의 위치 바꾸기
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)
![]() |
|
'공부 > 파이썬 머신러닝 판다스 데이터 분석' 카테고리의 다른 글
[판다스 입문/산술연산] 시리즈 연산 (0) | 2022.10.18 |
---|---|
[판다스 입문/산술연산] (0) | 2022.10.18 |
[판다스 입문/인덱스 활용] (0) | 2022.10.14 |
[판다스 입문/판다스 자료구조] 시리즈 (0) | 2022.10.12 |
[판다스 입문/판다스 자료구조] (0) | 2022.10.12 |