호쌤
호쌤 Just For Fun

[Python 데이터 분석] 데이터 프레임

크리에이티브 커먼즈 라이선스 ITPAPER(호쌤,쭈쌤)에 의해 작성된 ≪[Python 데이터 분석] 데이터 프레임≫은(는) 크리에이티브 커먼즈 저작자표시-비영리-동일조건변경허락 4.0 국제 라이선스에 따라 이용할 수 있습니다.
이 라이선스의 범위 이외의 이용허락을 얻기 위해서는 leekh4232@gmail.com으로 문의하십시오.

[Python 데이터 분석] 데이터 프레임

데이터프레임(DataFrame)은 행과 열로 구성된 사각형의 표 형식의 자료구조 로서 데이터 분석에서 가장 유용하며 필수불가결한 자료형입니다. 데이터프레임이라는 용어가 낯설다면 엑셀과 같은 분석 프로그램의 시트(sheet) 데이터를 구현하기 위한 자료형이라고 생각하면 이해하기 쉽습니다.

  • 엑셀의 표 형태로 구성된 데이터분석의 가장 기본적인 자료구조
  • 으로 구성된다.
    • : column이나 변수라고도 부름
    • : row나 index라고도 부름
  • 열 > 행 순으로 값에 접근한다.

#01. 필수 패키지 참조

1) xlsx 파일을 불러오기 위한 의존성 설치

엑셀 파일로부터 DataFrame을 생성하기 위해서는 pandas 모듈 내의 ExcelFile 클래스가 의존하는 모듈들을 추가적으로 설치해야 한다.

1
2
pip install --upgrade openpyxl
pip install --upgrade xlrd

2) 패키지 가져오기

1
2
3
4
# pandas 패키지에서 참조
from pandas import DataFrame    # 데이터프레임 클래스
from pandas import read_csv     # csv파일을 읽어들이기 위한 함수
from pandas import ExcelFile    # Excel 파일을 읽어들이기 위한 클래스

#02. 데이터프레임을 생성하기

1
리턴받을객체 = DataFrame(데이터, index=[인덱스 이름을 위한 리스트], columns=[컬럼 이름을 위한 리스트])

1) 데이터의 종류

  1. 2차원 리스트
  2. 리스트를 원소로 갖는 딕셔너리
  3. 동일한 구조를 갖는 딕셔너리들이 모인 리스트
  4. csv 파일
  5. xlsx 파일

2) 2차원 리스트를 사용한 DataFrame 생성

기본 생성

각각의 1차 리스트개 DataFrame에서 하나의 행으로 지정된다.

컬럼과 인덱스 이름은 0부터 순차적으로 일련번호가 부여된다.

DataFrame에서 빈값은 None으로 지정한다. 이는 조사 과정에서 측정되지 않은 상태를 의미하며 이러한 형태의 빈 값을 결측치라고 한다.

1
2
3
4
5
6
7
8
9
10
source = [
    [1, '남자', 98, 88, 64],
    [2, '여자', 88, 90, 62, 72],
    [1, '남자', 92, 70, None, None],
    [3, '여자', 63, 60, 31, 70],
    [4, '남자', 120, 50, None, 88]
]

df = DataFrame(source)
df
▶ 출력결과
0 1 2 3 4 5
0 1 남자 98 88 64.0 NaN
1 2 여자 88 90 62.0 72.0
2 1 남자 92 70 NaN NaN
3 3 여자 63 60 31.0 70.0
4 4 남자 120 50 NaN 88.0

컬럼과 인덱스 이름 지정하기

1
2
3
4
df = DataFrame(source,
               columns=['학년', '성별', '국어', '영어', '수학', '과학'],
               index=['철수', '영희', '민수', '수현', '호영'])
df
▶ 출력결과
학년 성별 국어 영어 수학 과학
철수 1 남자 98 88 64.0 NaN
영희 2 여자 88 90 62.0 72.0
민수 1 남자 92 70 NaN NaN
수현 3 여자 63 60 31.0 70.0
호영 4 남자 120 50 NaN 88.0

3) 리스트를 원소로 갖는 딕셔너리를 사용한 DataFrame 생성

딕셔너리의 key가 컬럼의 이름으로 사용되기 때문에 index만 추가적으로 지정한다.

1
2
3
4
5
6
7
8
9
10
11
source = {
    '학년': [1, 2, 1, 3, 4],
    '성별': ['남자', '여자', '남자', '여자', '남자'],
    '국어': [98, 88, 92, 63, 120],
    '영어': [88, 90, 70, 60, 50],
    '수학': [64, 62, None, 31, None],
    '과학': [None, 72, None, 70, 88]
}

df = DataFrame(source, index=['철수', '영희', '민수', '수현', '호영'])
df
▶ 출력결과
학년 성별 국어 영어 수학 과학
철수 1 남자 98 88 64.0 NaN
영희 2 여자 88 90 62.0 72.0
민수 1 남자 92 70 NaN NaN
수현 3 여자 63 60 31.0 70.0
호영 4 남자 120 50 NaN 88.0

4) 동일한 구조를 갖는 딕셔너리들이 모인 리스트를 사용한 DataFrame 생성

딕셔너리의 key가 컬럼의 이름으로 사용되기 때문에 index만 추가적으로 지정한다.

1
2
3
4
5
6
7
8
9
10
source = [
    {'학년': 1, '성별': '남자', '국어': 98, '영어': 88, '수학': 64, '과학': None},
    {'학년': 2, '성별': '여자', '국어': 88, '영어': 90, '수학': 62, '과학': 72},
    {'학년': 1, '성별': '남자', '국어': 92, '영어': 70, '수학': None, '과학': None},
    {'학년': 3, '성별': '여자', '국어': 63, '영어': 60, '수학': 31, '과학': 70},
    {'학년': 4, '성별': '남자', '국어': 120, '영어': 50, '수학': None, '과학': 88}
]

df = DataFrame(source, index=['철수', '영희', '민수', '수현', '호영'])
df
▶ 출력결과
학년 성별 국어 영어 수학 과학
철수 1 남자 98 88 64.0 NaN
영희 2 여자 88 90 62.0 72.0
민수 1 남자 92 70 NaN NaN
수현 3 여자 63 60 31.0 70.0
호영 4 남자 120 50 NaN 88.0

5) CSV파일을 DataFrame으로 변환하기

1
리턴받을객체 = read_csv(파일경로 [, encoding="euc-kr|utf-8"])
  • encoding의 기본값은 utf-8
    • MS-Office 2019 미만 버전에서 생성하는 경우 무조건 euc-kr
  • 파일경로는 상대경로, 절대경로, URL 형식이 가능함.

외부에서 csv나 xlsx 파일을 가져오는 경우 index가 인식되지 않기 때문에 특정 컬럼의 값들을 인덱스로 지정하고 그 컬럼을 삭제하는 전처리가 필요하다. (뒤에서 다룹니다.)

1
2
df = read_csv('http://itpaper.co.kr/demo/py/grade.csv', encoding='euc-kr')
df
▶ 출력결과
이름 학년 성별 국어 영어 수학 과학
0 철수 1 남자 98 NaN 88.0 64.0
1 영희 2 여자 88 90.0 62.0 72.0
2 민수 1 남자 92 70.0 NaN NaN
3 수현 3 여자 63 60.0 31.0 70.0
4 호영 4 남자 120 50.0 NaN 88.0

6) xlsx 파일을 통한 생성

엑셀파일을 객체 형태로 가져온다.

1
2
xls = ExcelFile('http://itpaper.co.kr/demo/py/grade.xlsx')
xls
▶ 출력결과
1
<pandas.io.excel._base.ExcelFile at 0x294619be4e0>

엑셀 파일의 sheet이름에 대한 리스트

1
xls.sheet_names
▶ 출력결과
1
['grade']

가져오고자 하는 sheet 이름을 지정하여 데이터프레임으로 변환

1
2
df = xls.parse(xls.sheet_names[0])
df
▶ 출력결과
이름 학년 성별 국어 영어 수학 과학
0 철수 1 남자 98 NaN 88.0 64.0
1 영희 2 여자 88 90.0 62.0 72.0
2 민수 1 남자 92 70.0 NaN NaN
3 수현 3 여자 63 60.0 31.0 70.0
4 호영 4 남자 120 50.0 NaN 88.0

#03. 데이터에 접근하기

1) 데이터 개요 확인

데이터의 크기

튜플 타입으로 행,열의 크기가 반환된다.

1
2
size = df.shape
size
▶ 출력결과
1
(5, 7)

튜플이므로 행과 열을 구성하는 변수에 나누어 저장 가능

1
2
3
rows, cols = df.shape
print(rows)
print(cols)
▶ 출력결과
1
2
5
7

상위 3건 확인하기

파라미터를 생략할 경우 상위 5건을 반환한다.

1
2
top3 = df.head(3)
top3
▶ 출력결과
이름 학년 성별 국어 영어 수학 과학
0 철수 1 남자 98 NaN 88.0 64.0
1 영희 2 여자 88 90.0 62.0 72.0
2 민수 1 남자 92 70.0 NaN NaN

하위 3건 확인하기

파라미터를 생략할 경우 하위 5건을 반환한다.

1
2
last3 = df.tail(3)
last3
▶ 출력결과
이름 학년 성별 국어 영어 수학 과학
2 민수 1 남자 92 70.0 NaN NaN
3 수현 3 여자 63 60.0 31.0 70.0
4 호영 4 남자 120 50.0 NaN 88.0

인덱스 이름 확인

1
df.index
▶ 출력결과
1
RangeIndex(start=0, stop=5, step=1)
인덱스 이름을 리스트로 변환
1
2
i_list = list(df.index)
i_list
▶ 출력결과
1
[0, 1, 2, 3, 4]

컬럼 이름 확인

1
df.columns
▶ 출력결과
1
Index(['이름', '학년', '성별', '국어', '영어', '수학', '과학'], dtype='object')

인덱스 이름을 리스트로 변환

1
2
c_list = list(df.columns)
c_list
▶ 출력결과
1
['이름', '학년', '성별', '국어', '영어', '수학', '과학']

데이터의 값들만 확인

2차 배열로 반환된다.

1
2
print(type(df.values))
df.values
▶ 출력결과
1
2
3
4
5
6
7
<class 'numpy.ndarray'>

array([['철수', 1, '남자', 98, nan, 88.0, 64.0],
       ['영희', 2, '여자', 88, 90.0, 62.0, 72.0],
       ['민수', 1, '남자', 92, 70.0, nan, nan],
       ['수현', 3, '여자', 63, 60.0, 31.0, 70.0],
       ['호영', 4, '남자', 120, 50.0, nan, 88.0]], dtype=object)

전치 구하기

행과 열이 서로 바뀐 형태

1
2
df_t = df.T
df_t
▶ 출력결과
0 1 2 3 4
이름 철수 영희 민수 수현 호영
학년 1 2 1 3 4
성별 남자 여자 남자 여자 남자
국어 98 88 92 63 120
영어 NaN 90 70 60 50
수학 88 62 NaN 31 NaN
과학 64 72 NaN 70 88

2) 단위의 데이터 접근

각 열별로 데이터 타입 확인

1
df.dtypes
▶ 출력결과
1
2
3
4
5
6
7
8
이름     object
학년      int64
성별     object
국어      int64
영어    float64
수학    float64
과학    float64
dtype: object

특정 열에 대한 타입과 값 확인

DataFrame의 각 열은 Series로 구성되어 있음을 알 수 있다.

1
2
print(type(df['국어']))
df['국어']
▶ 출력결과
1
2
3
4
5
6
7
8
<class 'pandas.core.series.Series'>

0     98
1     88
2     92
3     63
4    120
Name: 국어, dtype: int64

특정 열의 값들을 numpy 배열로 변환

1
2
3
arr = df['국어'].values
print(type(arr))
arr
▶ 출력결과
1
2
3
<class 'numpy.ndarray'>

array([ 98,  88,  92,  63, 120], dtype=int64)

열의 값들을 list로 변환

1
2
3
ls = list(df['국어'])
print( type(ls) )
ls
▶ 출력결과
1
2
3
<class 'list'>

[98, 88, 92, 63, 120]

3) 행 단위로 접근하기

반드시 loc이라는 속성을 통해서 접근해야 한다.

하나의 행에 속한 모든 데이터 추출

인덱스가 0인 행을 가져온다. 인덱스 이름이 문자열로 되어 있는 경우 해당 문자열을 지정한다.

1
2
3
cs = df.loc[0]
print(type(cs))
cs
▶ 출력결과
1
2
3
4
5
6
7
8
9
10
<class 'pandas.core.series.Series'>

이름     철수
학년      1
성별     남자
국어     98
영어    NaN
수학     88
과학     64
Name: 0, dtype: object

행의 값들을 numpy 배열로 변환

1
2
3
arr = df.loc[0].values
print(type(arr))
arr
▶ 출력결과
1
2
3
<class 'numpy.ndarray'>

array(['철수', 1, '남자', 98, nan, 88.0, 64.0], dtype=object)

행의 값들을 list로 변환

1
2
3
ls = list(df.loc[0])
print( type(ls) )
ls
▶ 출력결과
1
2
3
<class 'list'>

['철수', 1, '남자', 98, nan, 88.0, 64.0]

4). 특정 위치의 값에 직접 접근

열 > 행 순으로 접근하기 (읽기전용)

1
df['국어'][0]
▶ 출력결과
1
98

행 > 열 순으로 접근하기 (읽기,쓰기 겸용 / 권장)

1
df.loc[0,'국어']
▶ 출력결과
1
98

특정 값 변경하기 -> 행 우선 접근 방법으로만 가능

1
2
df.loc[0,'국어'] = 99
df
▶ 출력결과
이름 학년 성별 국어 영어 수학 과학
0 철수 1 남자 99 NaN 88.0 64.0
1 영희 2 여자 88 90.0 62.0 72.0
2 민수 1 남자 92 70.0 NaN NaN
3 수현 3 여자 63 60.0 31.0 70.0
4 호영 4 남자 120 50.0 NaN 88.0
Rating:

크리에이티브 커먼즈 라이선스 ITPAPER(호쌤,쭈쌤)에 의해 작성된 ≪[Python 데이터 분석] 데이터 프레임≫은(는) 크리에이티브 커먼즈 저작자표시-비영리-동일조건변경허락 4.0 국제 라이선스에 따라 이용할 수 있습니다.
이 라이선스의 범위 이외의 이용허락을 얻기 위해서는 leekh4232@gmail.com으로 문의하십시오.

comments powered by Disqus