파이썬: Pandas 기본
Pandas
Pandas란?
- 수치형 테이블, 시계열 데이터를 조작/운용하는데 편의성을 제공하는 라이브러리
- 관행적으로 ‘pd’로 호출한다.
import pandas as pd
시리즈(Series)
- DataFrame의 하위 자료형
- NumPy의 ndarray와 달리, 다양한 형식의 데이터를 함께 담을 수 있다.
데이터프레임(DataFrame)
- 행과 열로 이루어진 표 형태의 자료형
- R에서 사용되는 data.frame 구조를 본떠서 만들어짐
- 1개의 열이 시리즈, 이 시리즈가 다수 모여 데이터프레임을 형성한다.
Pandas의 기초 기능
1. 시리즈(Series) 생성
'’리스트’‘로 시리즈 생성
- 리스트 내 데이터 형식이 각각 달라도 시리즈로 생성할 수 있다.
- 실행 결과, 좌측에 나타난 값은 ‘인덱스(줄번호)’로 자동으로 생성된다.
s = pd.Series([1,2,3,'a','b','c']) # 데이터가 형식이 달라도 시리즈로 만들 수 있다.
s
0 1
1 2
2 3
3 a
4 b
5 c
dtype: object # int와 문자열이 섞였으므로 dtype은 object로 표시된다.
# 특징: 자동으로 인덱스(줄번호)를 생성해준다.
'’딕셔너리’‘로 시리즈 생성
- 딕셔너리로 시리즈 생성시엔, ‘key’가 인덱스로 활용된다. (위의 리스트는 자동으로 인덱스 생성)
- 보통은 리스트로 시리즈를 생성하지만, 이 역시 알아두면 좋다.
s = pd.Series({'kor':65, 'eng':78, 'math':89})
s
kor 65
eng 78
math 89
dtype: int6
# key가 인덱스로 자동으로 지정되었음을 확인할 수 있다.
시리즈의 속성(인덱스/값) 반환
- 인덱스 반환 : series.index
- 값 반환: series.values
s = pd.Series([1, 3, 5, 6, 8])
s.index
RangeIndex(start=0, stop=5, step=1)
s.values
array([1, 3, 5, 6, 8], dtype=int64)
2. DataFrame 생성
- 리스트로 생성
- pd.DataFrame(data, [index, columns]) # [] 생략가능, 각각 리스트로 받아옴
# index, column 이름을 지정하지 않으면, 자동으로 숫자가 설정된다.
data = [[1,2,3],[4,5,6],[7,8,9]]
d1 = pd.DataFrame(data)
d1
0 1 2
0 1 2 3
1 4 5 6
2 7 8 9
# 줄이름(index), 열이름(columns) 직접 설정하여 데이터프레임 생성(by list)
index = ['stu1', 'stu2', 'stu3', 'stu4']
cols = ['name', 'num', 'kor', 'eng', 'math']
vals = [['aaa', 1, 54, 56, 67],
['bbb', 2, 98, 76, 56],
['ccc', 3, 78, 89, 54],
['ddd', 4, 96, 35, 86]]
d2 = pd.DataFrame(vals, index=index, columns=cols)
d2
name num kor eng math
stu1 aaa 1 54 56 67
stu2 bbb 2 98 76 56
stu3 ccc 3 78 89 54
stu4 ddd 4 96 35 86
- 딕셔너리로 데이터프레임 생성
- key → 컬럼명으로 활용된다.
# 딕셔너리로 데이터프레임 생성
dic = {
'name': ['aaa', 'bbb', 'ccc', 'ddd'],
'num': [1,2,3,4],
'kor': [76,56,87,76],
'eng': [89,56,45,54],
'math': [98,56,43,87]
}
idx = np.arange(1,5) # 인덱스도 원하는 숫자로 정의
d3 = pd.DataFrame(dic, index=idx)
d3
name num kor eng math
1 aaa 1 76 89 98
2 bbb 2 56 56 56
3 ccc 3 87 45 43
4 ddd 4 76 54 87
데이터프레임의 속성(인덱스/컬럼명/값) 반환
- 인덱스 반환 :dataframe.index
- 컬럼명 반환: dataframe.columns
- 값 반환: dataframe.values
3. 데이터 연산
(1) 시리즈 연산 (+, -, *, /)
a=pd.Series([1,2,3,4])
b=pd.Series([5,6,7,8])
a+b
0 6
1 8
2 10
3 12
dtype: int64
a-b
0 -4
1 -4
2 -4
3 -4
dtype: int64
a*b
0 5
1 12
2 21
3 32
dtype: int64
b/a
0 5.000000
1 3.000000
2 2.333333
3 2.000000
dtype: float64
# 두 시리즈의 크기가 다른 경우, 해당 위치의 계산값은 NaN이 된다.
a=pd.Series([1,2,3])
b=pd.Series([5,6,7,8])
a+b
0 6.0
1 8.0
2 10.0
3 NaN
dtype: float64
(2) 데이터프레임 연산 (+, -, *, /)
- 사이즈가 다른 두 데이터프레임의 연산 결과
d1 = pd.DataFrame({'A':[1,2,3], 'B':[4,5,6], 'C':[7,8,9]})
d1
A B C
0 1 4 7
1 2 5 8
2 3 6 9
d2 = pd.DataFrame({'A':[11,22], 'B':[33,44], 'C':[55,66]})
d2
A B C
0 11 33 55
1 22 44 66
d1+d2
# index가 2인 줄은 연산결과 값이 전부 NaN
A B C
0 12.0 37.0 62.0
1 24.0 49.0 74.0
2 NaN NaN NaN
4. 데이터프레임 통계함수
- 데이터프레임에서 다양한 통계값들을 구해주는 함수를 활용할 수 있다.
sum() | mean() | std() | var() | min() | max() | cumsum() | cumpord() |
---|---|---|---|---|---|---|---|
합 | 평균 | 표준편차 | 분산 | 최소값 | 최대값 | 누적합 | 누적곱 |
df.sum() # 컬럼별 총합(axis=0이 기본값)
df.mean() # 컬럼별 평균(axis=0이 기본값)
df.mean(axis=1) # 레코드별 평균
- 종합적인 통계를 한번에 보는 방법: df.describe()
df.describe() # 통계를 종합적으로 보게 해줌
국어 | 영어 | 수학 | 사회 | 과학 | |
---|---|---|---|---|---|
count | 3.0 | 3.0 | 3.000000 | 3.000000 | 3.000000 |
mean | 65.0 | 56.0 | 84.000000 | 73.000000 | 80.666667 |
std | 11.0 | 11.0 | 12.165525 | 26.627054 | 21.733231 |
min | 54.0 | 45.0 | 76.000000 | 45.000000 | 56.000000 |
25% | 59.5 | 50.5 | 77.000000 | 60.500000 | 72.500000 |
50% | 65.0 | 56.0 | 78.000000 | 76.000000 | 89.000000 |
75% | 70.5 | 61.5 | 88.000000 | 87.000000 | 93.000000 |
max | 76.0 | 67.0 | 98.000000 | 98.000000 | 97.000000 |
5. 데이터프레임의 요소 추출(접근)
- 데이터프레임 요소 추출은 정말로 자주 쓰이는 편
- 따라서, 여러 방법을 숙지하고 있어야 상황에 맞는 적절한 요소 접근이 가능하다.
# 요소접근을 위한 예시 데이터프레임 생성
d = np.arange(100).reshape(10,10)
d = pd.DataFrame(d)
- d는 다음과 같다.
# 다양한 요소 접근 방법
d.head(3) # 맨 위부터 3줄(기본값: 5줄)
d.tail(2) # 맨 뒤부터 2줄(기본값: 5줄)
d[2:5] # 인덱스 범위 지정(2~4번줄)
d.loc[3] # .loc[인덱스명]: 인덱스 이름이 3인 줄을 반환
# 요소접근을 위한 예시 데이터프레임 생성2
s = ['a','b','c','d','e','f','g','h','i','j']
s2 = ['c_a','c_b','c_c','c_d','c_e','c_f','c_g','c_h','c_i','c_j']
d2 = pd.DataFrame(d, index=s, columns=s2)
- d2는 다음과 같다.
# 다양한 요소 접근 방법
d2.loc['c':'h'] # 인덱스명이 'c'인 레코드부터 'h'인 레코드까지 반환
d2['c_b'] # 컬럼명이 'c_b'인 컬럼 전체
d2['c_b']['c':'f'] # df[col][idx] # 컬럼명이 'c_b'이면서 인덱스가 c~f 사이인 값들
d2.loc['e']['c_e']# .loc[idx][col] <- 순서에 주의
d2.loc['e','c_e'] # .loc[idx,col] 위와 같은 결과
d2['c_e'][1] # df[col][idx_num]인덱스는 위치로도 표현 가능 # 'c_e'컬럼의 인덱스번호가 1인 값
d2['c_e'].loc['f'] # df[col].loc[idx] # 'c_e' 컬럼 중 f 인덱스의 값
d2[d3.columns[1:-1]].loc['f'] # df[col].loc[idx] # 두번째~맨뒤에서 두번째 컬럼의 f 인덱스 값
6. 데이터프레임 통합
- 세로로 통합: df1.append(df2)
- 가로로 통합: df1.join(df2)
- 특정 컬럼 기준으로 가로로 병합: df1.merge(df2)
# 세로로 통합(append)
d1 = pd.DataFrame({'A':[78,67,54,34], 'B':[87,67,65,34]})
d2 = pd.DataFrame({'A':[76,54], 'B':[87,56]})
d3 = d1.append(d2)
print(d1)
print(d2)
print(d3)
A B
0 78 87
1 67 67
2 54 65
3 34 34
A B
0 76 87
1 54 56
A B
0 78 87
1 67 67
2 54 65
3 34 34
0 76 87
1 54 56 <- 인덱스가 원래 인덱스 그대로 들어가는 것을 확인할 수 있다.
d1.append(d2, ignore_index=True) # 원래 인덱스 무시, 새롭게 인덱스 부여
A B
0 78 87
1 67 67
2 54 65
3 34 34
4 76 87
5 54 56
# 가로로 통합(join)
d3 = pd.DataFrame({'C':[65,43,32]})
d1.join(d3)
A B C
0 78 87 65.0
1 67 67 43.0
2 54 65 32.0
3 34 34 NaN <- d3의 인덱스 수가 하나 부족하므로 NaN이 된다.
# d1
판매월 A B
0 1월 54 87
1 2월 65 65
2 3월 76 54
3 4월 78 43
# d2
판매월 C D
0 1월 54 98
1 2월 43 87
2 3월 32 76
3 4월 54 45
# 가로로 병합(merge())
d1.merge(d2) # 병합 기준이 되는 컬럼은 자연스럽게 합쳐짐
판매월 A B C D
0 1월 54 87 54 98
1 2월 65 65 43 87
2 3월 76 54 32 76
3 4월 78 43 54 45
merge함수의 how option(inner, left, right, outer)
- SQL에서의 join과 동일하다.
# d1
판매월 A B
0 1월 54 87
1 2월 65 65
2 3월 76 54
3 4월 78 43
# d2
판매월 C D
0 3월 54 98
1 4월 43 87
2 5월 32 76
3 6월 54 45
# inner join(default)
d1.merge(d2) #how 기본 값: inner # 지정된 열의 공통된 값만
판매월 A B C D
0 3월 76 54 54 98
1 4월 78 43 43 87 -> d1과 d2에서 판매월이 공통되는 부분끼리만 병합
# left join
d1.merge(d2, how='left')
판매월 A B C D
0 1월 54 87 NaN NaN
1 2월 65 65 NaN NaN
2 3월 76 54 54.0 98.0
3 4월 78 43 43.0 87.0 -> 왼쪽(d1)은 전부 다, 오른쪽은 겹치는 부분만 병합, 나머지는 NaN
# right join
d1.merge(d2, how='right')
판매월 A B C D
0 3월 76.0 54.0 54 98
1 4월 78.0 43.0 43 87
2 5월 NaN NaN 32 76
3 6월 NaN NaN 54 45 -> 오른쪽(d2)은 전부 다, 왼쪽은 겹치는 부분만 병합, 나머지는 NaN
# outer join
d1.merge(d2, how='outer')
판매월 A B C D
0 1월 54.0 87.0 NaN NaN
1 2월 65.0 65.0 NaN NaN
2 3월 76.0 54.0 54.0 98.0
3 4월 78.0 43.0 43.0 87.0
4 5월 NaN NaN 32.0 76.0
5 6월 NaN NaN 54.0 45.0
7. 파일 입출력
- 파일 입력: pd.read_csv(파일명, index_col =’컬럼명’)
- 인덱스로 사용할 컬럼을 지정하여 파일 입력(index_col 지정 안하면 자동배정)
- 파일 출력: df.to_csv(만들파일명)
# 파일 입력
pd.read_csv('a.csv', index_col='이름') # '이름' 컬럼을 인덱스로 해서 파일 읽기
국어 영어 수학
이름
aaa 43 54 65
bbb 7 67 87
ccc 54 65 76
# 파일 출력
d1.to_csv('b.csv', encoding='utf-8') # d1 데이터프레임을 b.csv에 저장
Leave a comment