Pandas는 Numpy의 2차원 배열에서 가능한 대부분의 데이터 처리가 가능하며 추가로 데이터 처리 및 변환을 위한 다양한 함수와 메서드를 제공한다.
데이터 갯수 세기
가장 간단한 데이터 분석은 데이터의 갯수를 세는 것이나. count
메서드를 사용하는데, 주의할 점은 NaN값은 세지 않는다는 것이다.
0 0.0
1 1.0
2 2.0
3 NaN
4 4.0
5 5.0
6 6.0
7 7.0
8 8.0
9 9.0
dtype: float64
9
데이터프레임에서는 각 열마다 별도로 데이터 갯수를 센다. 데이터에서 값이 누락된 부분을 찾을 때 유용하다.
index | 0 | 1 | 2 | 3 |
---|---|---|---|---|
0 | 0.0 | 0.0 | 3.0 | 2.0 |
1 | 3.0 | 0.0 | 2.0 | 1.0 |
2 | 3.0 | 2.0 | 4.0 | NaN |
3 | 4.0 | 3.0 | 4.0 | 2.0 |
0 4
1 4
2 4
3 3
dtype: int64
카테고리 값 세기
Series의 값이 정수, 문자열, 카테고리 값인 경우에는 value_counts 매서드로 각각의 값이 나온 횟수를 셀 수 있다.
95 4
96 5
97 2
98 4
99 3
dtype: int32
1 22
0 18
4 17
5 16
3 14
2 13
dtype: int64
DataFrame에는 value_counts
매서드가 없으므로 각 열마다 별도 확인 해야 한다.
3.0 2
4.0 1
0.0 1
Name: 0, dtype: int64
정렬
데이터를 정렬하려면 sort_index
와 sord_values
매서드를 사용한다. sort_index
는 인덱스 값을 기준으로, sort_values
는 데이터 값을 기준으로 정렬한다.
앞서 s2
Series의 각 데이터 값에 따른 데이터 갯수를 보기좋게 정렬하려면 sort_index
를 사용한다.
0 18
1 22
2 13
3 14
4 17
5 16
dtype: int64
NaN값이 있는 경우에는 정렬하면 NaN값은 마지막에 위치한다.
0 0.0
1 1.0
2 2.0
4 4.0
5 5.0
6 6.0
7 7.0
8 8.0
9 9.0
3 NaN
dtype: float64
큰 수에서 작은 수로 반대방향 정렬하려면 ascending=False
인수를 지정한다.
9 9.0
8 8.0
7 7.0
6 6.0
5 5.0
4 4.0
2 2.0
1 1.0
0 0.0
3 NaN
dtype: float64
DataFrame에서 sort_values
매서드를 사용하려면 by
인수로 정렬 기준이 되는 열을 지정해 주어야 한다.
index | 0 | 1 | 2 | 3 |
---|---|---|---|---|
0 | 0.0 | 0.0 | 3.0 | 2.0 |
1 | 3.0 | 0.0 | 2.0 | 1.0 |
2 | 3.0 | 2.0 | 4.0 | NaN |
3 | 4.0 | 3.0 | 4.0 | 2.0 |
by
인수에 리스트 값을 넣으면 이 순서대로 정렬 기준이 우선순위가 된다.
index | 0 | 1 | 2 | 3 |
---|---|---|---|---|
1 | 3.0 | 0.0 | 2.0 | 1.0 |
0 | 0.0 | 0.0 | 3.0 | 2.0 |
2 | 3.0 | 2.0 | 4.0 | NaN |
3 | 4.0 | 3.0 | 4.0 | 2.0 |
행/열 합계
행과 열의 합계를 구할 때는 sum(axis)
매서드를 사용한다.
- 행 합계 : axis=1
- 열 합계 : axis=0 (기본값이므로 생략 가능)
index | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|---|
0 | 5 | 8 | 9 | 5 | 0 | 0 | 1 | 7 |
1 | 6 | 9 | 2 | 4 | 5 | 2 | 4 | 2 |
2 | 4 | 7 | 7 | 9 | 1 | 7 | 0 | 6 |
3 | 9 | 9 | 7 | 6 | 9 | 1 | 0 | 1 |
0 35
1 34
2 41
3 42
dtype: int64
0 24
1 33
2 25
3 24
4 15
5 10
6 5
7 16
dtype: int64
행과 열의 합을 행/열에 추가해보자.
index | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | row_sum |
---|---|---|---|---|---|---|---|---|---|
0 | 5 | 8 | 9 | 5 | 0 | 0 | 1 | 7 | 35 |
1 | 6 | 9 | 2 | 4 | 5 | 2 | 4 | 2 | 34 |
2 | 4 | 7 | 7 | 9 | 1 | 7 | 0 | 6 | 41 |
3 | 9 | 9 | 7 | 6 | 9 | 1 | 0 | 1 | 42 |
index | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | row_sum |
---|---|---|---|---|---|---|---|---|---|
0 | 5.0 | 8.0 | 9.0 | 5.0 | 0.0 | 0.0 | 1.0 | 7.0 | 35.0 |
1 | 6.0 | 9.0 | 2.0 | 4.0 | 5.0 | 2.0 | 4.0 | 2.0 | 34.0 |
2 | 4.0 | 7.0 | 7.0 | 9.0 | 1.0 | 7.0 | 0.0 | 6.0 | 41.0 |
3 | 9.0 | 9.0 | 7.0 | 6.0 | 9.0 | 1.0 | 0.0 | 1.0 | 42.0 |
col_sum | 24.0 | 33.0 | 25.0 | 24.0 | 15.0 | 10.0 | 5.0 | 16.0 | 152.0 |
apply 변환
행이나 열 단위로 더 복잡한 처리를 하고 싶을 때는 apply
매서드를 사용한다. 인수로 행 또는 열을 받는 함수를 apply
매서드의 인수로 넣으면 각 열(또는 행)을 반복하여 그 함수에 적용시킨다.
index | A | B | C |
---|---|---|---|
0 | 1 | 2 | 1 |
1 | 3 | 3 | 5 |
2 | 4 | 1 | 2 |
3 | 3 | 2 | 4 |
4 | 4 | 3 | 4 |
예를 들어 각 열의 최대값과 최소값의 차이를 구하고 싶으면 다음과 같은 람다 함수를 넣는다.
A 3
B 2
C 4
dtype: int64
마찬가지로 행에 대해 적용하고 싶다면 axis=1
인수를 추가해 주면 된다.
0 1
1 2
2 3
3 2
4 1
dtype: int64
각 열에 대해 어떤값이 얼마나 사용되고 있는지 알고 싶다면 value_counts
함수를 넣을 수도 있다.
index | A | B | C |
---|---|---|---|
1 | 1.0 | 1.0 | 1.0 |
2 | NaN | 2.0 | 1.0 |
3 | 2.0 | 2.0 | NaN |
4 | 2.0 | NaN | 2.0 |
5 | NaN | NaN | 1.0 |
NaN 값은 fillna 매서드를 사용하여 원하는 값으로 바꿀 수 있다. astype 매서드로 전체 데이터의 자료형을 바꾸는 것도 가능하다.
index | A | B | C |
---|---|---|---|
1 | 1 | 1 | 1 |
2 | 0 | 2 | 1 |
3 | 2 | 2 | 0 |
4 | 2 | 0 | 2 |
5 | 0 | 0 | 1 |
실수 값을 카테고리 값으로 변환
실수 값을 크기 기준으로 하여 카테고리 값으로 변환하고 싶을 때는 다음과 같은 명령을 사용한다.
- cut : 실수 값의 경계선을 지정하는 경우
- qcut : 갯수가 똑같은 구간으로 나누는 경우
cut
명령을 사용하면 실수값을 다음처럼 카테고리 값으로 바꿀 수 있다. bins
인수는 카테고리를 나누는 기준값이 된다. 영역을 넘는 값은 NaN으로 처리된다.
[NaN, '미성년자', '미성년자', '청년', '청년', ..., '노년', '청년', '장년', '중년', NaN]
Length: 12
Categories (5, object): ['미성년자' < '청년' < '중년' < '장년' < '노년']
cut
명령이 반환하는 값은 Categorical
클래스 객체이다. 이 객체는 categories
속성으로 라벨 문자열을, codes
속성으로 정수로 인코딩한 카테고리 값을 가진다.
pandas.core.arrays.categorical.Categorical
Index(['미성년자', '청년', '중년', '장년', '노년'], dtype='object')
array([-1, 0, 0, 1, 1, 3, 2, 4, 1, 3, 2, -1], dtype=int8)
index | ages | age_cat |
---|---|---|
0 | 0 | NaN |
1 | 2 | 미성년자 |
2 | 10 | 미성년자 |
3 | 21 | 청년 |
4 | 23 | 청년 |
5 | 37 | 장년 |
6 | 31 | 중년 |
7 | 61 | 노년 |
8 | 20 | 청년 |
9 | 41 | 장년 |
10 | 32 | 중년 |
11 | 100 | NaN |
정말 쉽게 데이터를 정의한 카테고리기준으로 분류 하였다!
qcut
명령은 구각 경계선을 지정하지 않고 데이터 갯수가 같도록 지정한 수의 구간으로 나눈다. 예를 들어 다음 코드는 1000개의 데이터를 4개의 구간으로 나누는데 각 구간은 250개씩 데이터를 가진다.
['Q2', 'Q1', 'Q2', 'Q3', 'Q1', ..., 'Q1', 'Q1', 'Q4', 'Q4', 'Q2']
Length: 1000
Categories (4, object): ['Q1' < 'Q2' < 'Q3' < 'Q4']
Q4 250
Q3 250
Q2 250
Q1 250
dtype: int64
성적을 비유하여 생각해보면 cut
은 절대평가 기준이 되는 점수에 의해 분류가 되는 것이고 qcut
은 상대평가 즉 점수의 순서대로 정렬하고 특정 수만큼씩 분류하는 것이라고 생각하면 될듯 싶다.
출처 : 데이터사이언스 스쿨(datascienceschool.net)