파이썬 pandas 라이브러리에 대한 모든 것
이 글은 파이썬 pandas 라이브러리의 사용법을 정리한다. Series와 DataFrame의 생성·인덱싱·연산부터 concat, merge, groupby, pivot, 결측값 처리까지 타이타닉 데이터 실습과 함께 다룬다.
라이브러리 불러오기
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
import math
Series
- pandas의 기본 객체 중 하나
- numpy의 ndarray를 기반으로 인덱싱을 기능을 추가하여 1차원 배열을 나타냄
- index를 지정하지 않을 시, 기본적으로 ndarray와 같이 0-based 인덱스 생성, 지정할 경우 명시적으로 지정된 index를 사용
- 같은 타입의 0개 이상의 데이터를 가질 수 있음
pd.Series([1, 2, 3])

pd.Series(['a', 'b', 'c'])

pd.Series(np.arange(200))
0 0
1 1
2 2
3 3
4 4
...
195 195
196 196
197 197
198 198
199 199
Length: 200, dtype: int32
data와 index 함께 명시하기
pd.Series([1,2,3], ['a','m','k']) # 첫번째는 data, 두번째는 인덱스 값
a 1
m 2
k 3
dtype: int64
data, index, data type 함께 명시하기(dtype)
s6 =pd.Series(np.arange(5), np.arange(100, 105), dtype=np.int16)
s6
100 0
101 1
102 2
103 3
104 4
dtype: int16
인덱스 활용하기
s = pd.Series([1, 1, 2, 1, 2, 2, 2, 1, 1, 3, 3, 4, 5, 5, 7, np.NaN]) #np.Nan는 결측치
s
0 1.0
1 1.0
2 2.0
3 1.0
4 2.0
5 2.0
6 2.0
7 1.0
8 1.0
9 3.0
10 3.0
11 4.0
12 5.0
13 5.0
14 7.0
15 NaN
dtype: float64
index 값
s6.index
Int64Index([100, 101, 102, 103, 104], dtype='int64')
values 값
s6.values
array([0, 1, 2, 3, 4], dtype=int16)
Series 함수
size
- 개수 반환
len(s)
16
s.size
16
shape
- 튜플형태로 shape반환
s.shape
(16,)
unique
- 유일한 값만 ndarry로 반환
s.unique() #unique는 중복x 한개의 문자만 가져옴
array([ 1., 2., 3., 4., 5., 7., nan])
count
- NaN을 제외한 개수를 반환
s.count() #실제 값만 카운트해서 반환
5
mean
- NaN을 제외한 평균
s.mean()
2.6666666
value_counts
- NaN을 제외하고 각 값들의 빈도를 반환
- 데이터의 개수 빈도를 알고 싶을때 가장 많이 쓰는 함수 중 하나
- index를 활용하여 멀티플한 값에 접근
- 갖고오고 싶은 인덱스를 리스트 형식으로 해서 반환
s.value_counts()
1.0 5
2.0 4
5.0 2
3.0 2
7.0 1
4.0 1
dtype: int64
head()
- head : 상위 n개 출력 기본 5개
s.head(n=7) #기본적으로 상위 5개
0 1.0
1 1.0
2 2.0
3 1.0
4 2.0
5 2.0
6 2.0
dtype: float64
tail()
- tail : 하위 n개 출력 기본 5개
s.tail() #기본적으로 하위 5개
11 4.0
12 5.0
13 5.0
14 7.0
15 NaN
dtype: float64
산술연산
- Series의 경우에도 스칼라와의 연산은 각 원소별로 스칼라와의 연산이 적용
- Series와의 연산은 각 인덱스에 맞는 값끼리 연산이 적용
- 이때, 인덱스의 pair가 맞지 않으면, 결과는 NaN
s = pd.Series(np.arange(10), np.arange(10)+1)
s
1 0
2 1
3 2
4 3
5 4
6 5
7 6
8 7
9 8
10 9
dtype: int32
조건식
s[s>5] # True인 것만 필터링해서 가져옴
7 6
8 7
9 8
10 9
dtype: int32
s[s % 2 == 0]
1 0
3 2
5 4
7 6
9 8
dtype: int32
s[s.index > 5] # s의 index를 기준으로 반환
6 5
7 6
8 7
9 8
10 9
dtype: int32
s[(s > 5) & (s < 8)] #괄호를 반드시 묶어줘야 한다.
7 6
8 7
dtype: int32
(s >= 7).sum() # boolean array의 참 개수를 구하는 것
3
s = pd.Series(np.arange(100, 105), ['a', 'b', 'c', 'd', 'e'])
s
a 100
b 101
c 102
d 103
e 104
dtype: int32
s['a'] = 200 # 이미 있는 건 갱신
s
a 200
b 101
c 102
d 103
e 104
dtype: int32
s['k'] = 300 # 없는 건 추가
s
a 200
b 101
c 102
d 103
e 104
k 300
dtype: int64
drop()
- drop은 s 자체에는 지워지지 않는다.
- 기본 inplace 값은 false. true이면 그 자체에 반환
- p.s. del은 원본에 바로 삭제
s.drop('k', inplace=True)
s
a 200
b 101
c 102
d 103
e 104
dtype: int64
update
s[['a', 'b']] = [300, 900] # 한꺼번에 update 가능
s
a 300
b 900
c 102
d 103
e 104
dtype: int64
Slicing
- 리스트, ndarray와 동일하게 적용
s1 = pd.Series(np.arange(100, 105))
s1
0 100
1 101
2 102
3 103
4 104
dtype: int32
s1[1:3]
1 101
2 102
dtype: int32
s2 = pd.Series(np.arange(100, 105), ['a', 'c', 'b', 'd', 'e'])
s2
a 100
c 101
b 102
d 103
e 104
dtype: int32
s2['c':'d'] # 문자열로 인덱싱 할때는 마지막 포함한다.
c 101
b 102
d 103
dtype: int32
concat
pd.concat(objs, # Series, DataFrame, Panel object
axis=0, # 0: 위+아래로 합치기, 1: 왼쪽+오른쪽으로 합치기
join='outer', # 'outer': 합집합(union), 'inner': 교집합(intersection)
join_axes=None, # axis=1 일 경우 특정 DataFrame의 index를 그대로 이용하려면 입력 (deprecated, 더이상 지원하지 않음)
ignore_index=False, # False: 기존 index 유지, True: 기존 index 무시
keys=None, # 계층적 index 사용하려면 keys 튜플 입력
levels=None,
names=None, # index의 이름 부여하려면 names 튜플 입력
verify_integrity=False, # True: index 중복 확인
copy=True) # 복사
axis = 0
- 위 + 아래로 DataFrame 합치기(rbind)
axis = 1
- 왼쪽 + 오른쪽으로 DataFrame 합치기(cbind)
join = ‘outer’
- 합집합(union)으로 DataFrame 합치기
join = ‘inner’
- 교집합(intersection)으로 DataFrame 합치기
join_axes
- axis=1일 경우 특정 DataFrame의 index를 그대로 이용하고자 할 경우
ignore_index
- 기존 index를 무시하고 싶을 때
keys
- 계층적 index (hierarchical index) 만들기
names
- index에 이름 부여하기
verify_integrity
- index 중복 여부 점검
merge
pd.merge(left, right, # merge할 DataFrame 객체 이름
how='inner', # left, rigth, inner (default), outer
on=None, # merge의 기준이 되는 Key 변수
left_on=None, # 왼쪽 DataFrame의 변수를 Key로 사용
right_on=None, # 오른쪽 DataFrame의 변수를 Key로 사용
left_index=False, # 만약 True 라면, 왼쪽 DataFrame의 index를 merge
Key로 사용
right_index=False, # 만약 True 라면, 오른쪽 DataFrame의 index를 merge Key로 사용
sort=True, # merge 된 후의 DataFrame을 join Key 기준으로 정렬
suffixes=('_x', '_y'), # 중복되는 변수 이름에 대해 접두사 부여 (defaults to '_x', '_y'
copy=True, # merge할 DataFrame을 복사
indicator=False) # 병합된 이후의 DataFrame에 left_only, right_only, both 등의 출처를 알 수 있는 부가 정보 변수 추가
DataFrame
- Series가 1차원이라면 DataFrame은 2차원으로 확대된 버젼
- Excel spreadsheet이라고 생각하면 이해하기 쉬움
- 2차원이기 때문에 인덱스가 row, column로 구성됨
- row는 각 개별 데이터를, column은 개별 속성을 의미
- Data Analysis, Machine Learning에서 data 변형을 위해 가장 많이 사용
DataFrame 생성하기
- 일반적으로 분석을 위한 데이터는 다른 데이터 소스(database, 외부 파일)을 통해 dataframe을 생성
- 여기서는 실습을 통해, dummy 데이터를 생성하는 방법을 다룰 예정
dictionary로 부터 생성하기
- dict의 key -> column
data = {'a' : 100, 'b' : 200, 'c' : 300}
pd.DataFrame(data, index=['x', 'y', 'z'])
| a | b | c | |
|---|---|---|---|
| x | 100 | 200 | 300 |
| y | 100 | 200 | 300 |
| z | 100 | 200 | 300 |
data = {'a' : [1, 2, 3], 'b' : [4, 5, 6], 'c' : [10, 11, 12]}
pd.DataFrame(data, index=[0, 1, 2])
| a | b | c | |
|---|---|---|---|
| 0 | 1 | 4 | 10 |
| 1 | 2 | 5 | 11 |
| 2 | 3 | 6 | 12 |
Series로 부터 생성하기
- 각 Series의 인덱스 -> column
a = pd.Series([100, 200, 300], ['a', 'b', 'd'])
b = pd.Series([101, 201, 301], ['a', 'b', 'k'])
c = pd.Series([110, 210, 310], ['a', 'b', 'c'])
pd.DataFrame([a, b, c], index=[100, 101, 102])
| a | b | d | k | c | |
|---|---|---|---|---|---|
| 100 | 100.0 | 200.0 | 300.0 | NaN | NaN |
| 101 | 101.0 | 201.0 | NaN | 301.0 | NaN |
| 102 | 110.0 | 210.0 | NaN | NaN | 310.0 |
# data 출처: https://www.kaggle.com/hesh97/titanicdataset-traincsv/data
train_data = pd.read_csv('F:/data/titanic/train.csv')
# ./ : 현재 폴더를 의미 # sep="," : 각각 데이터를 ,로 구분
head, tail 함수
- 데이터 전체가 아닌, 일부(처음부터, 혹은 마지막부터)를 간단히 보기 위한 함수
train_data.head(n=3)
| PassengerId | Survived | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 0 | 3 | Braund, Mr. Owen Harris | male | 22.0 | 1 | 0 | A/5 21171 | 7.2500 | NaN | S |
| 1 | 2 | 1 | 1 | Cumings, Mrs. John Bradley (Florence Briggs Th... | female | 38.0 | 1 | 0 | PC 17599 | 71.2833 | C85 | C |
| 2 | 3 | 1 | 3 | Heikkinen, Miss. Laina | female | 26.0 | 0 | 0 | STON/O2. 3101282 | 7.9250 | NaN | S |
train_data.tail(n=10)
| PassengerId | Survived | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 881 | 882 | 0 | 3 | Markun, Mr. Johann | male | 33.0 | 0 | 0 | 349257 | 7.8958 | NaN | S |
| 882 | 883 | 0 | 3 | Dahlberg, Miss. Gerda Ulrika | female | 22.0 | 0 | 0 | 7552 | 10.5167 | NaN | S |
| 883 | 884 | 0 | 2 | Banfield, Mr. Frederick James | male | 28.0 | 0 | 0 | C.A./SOTON 34068 | 10.5000 | NaN | S |
| 884 | 885 | 0 | 3 | Sutehall, Mr. Henry Jr | male | 25.0 | 0 | 0 | SOTON/OQ 392076 | 7.0500 | NaN | S |
| 885 | 886 | 0 | 3 | Rice, Mrs. William (Margaret Norton) | female | 39.0 | 0 | 5 | 382652 | 29.1250 | NaN | Q |
| 886 | 887 | 0 | 2 | Montvila, Rev. Juozas | male | 27.0 | 0 | 0 | 211536 | 13.0000 | NaN | S |
| 887 | 888 | 1 | 1 | Graham, Miss. Margaret Edith | female | 19.0 | 0 | 0 | 112053 | 30.0000 | B42 | S |
| 888 | 889 | 0 | 3 | Johnston, Miss. Catherine Helen "Carrie" | female | NaN | 1 | 2 | W./C. 6607 | 23.4500 | NaN | S |
| 889 | 890 | 1 | 1 | Behr, Mr. Karl Howell | male | 26.0 | 0 | 0 | 111369 | 30.0000 | C148 | C |
| 890 | 891 | 0 | 3 | Dooley, Mr. Patrick | male | 32.0 | 0 | 0 | 370376 | 7.7500 | NaN | Q |
변수 이름(column name, header)이 없는 파일 불러올 때 이름 부여하기
: names=[‘X1’,’X2’, ..], header=None
pd.read_csv('e:/data/text_without_column_name.txt', sep='|',
names=['ID','A','B','C','D'], header=None, index_col='ID')
#names=['ID', 'A', 'B', 'C', 'D'] 와 같이 칼럼 이름을 부여해줍니다.
# header=None 은 칼럼 이름이 없다는 뜻이며,
# 만약 1번째 행이 칼럼 이름이라면 header=0 으로 지정해주면 됩니다.
| A | B | C | D | |
|---|---|---|---|---|
| ID | ||||
| C1 | 1 | 2 | 3 | 4 |
| C2 | 5 | 6 | 7 | 8 |
| C3 | 1 | 3 | 5 | 7 |
유니코드 디코드 에러날때
-
cp949써보기 (encoding=’cp949’)
-
그래도 안되면
- encoding=’latin’
특정 줄은 제외하고 불러오기: skiprows = [x, x]
pd.read_csv('e:/data/text_without_column_name.txt', sep='|',
names=['ID','A','B','C','D'], header=None, index_col='ID',
skiprows=[1])
| A | B | C | D | |
|---|---|---|---|---|
| ID | ||||
| C1 | 1 | 2 | 3 | 4 |
| C3 | 1 | 3 | 5 | 7 |
nrows = n
- n 개의 행만 불러오기
- csv 파일의 위에서 부터 3개의 행(rows) 만 DataFrame으로 불러오기
csv_3 = pd.read_csv('f:/data/test_csv_file.csv', nrows=3); csv_3
| ID | LAST_NAME | AGE | |
|---|---|---|---|
| 0 | 1 | KIM | 30 |
| 1 | 2 | CHOI | 25 |
| 2 | 3 | LEE | 41 |
사용자 정의 결측값 기호 (custom missing value symbols)
df = pd.read_csv('e:/data/test_text_file.txt', sep='|',
na_values = ['?', '??', 'N/A', 'NA', 'nan', 'NaN', '-nan', '-NaN', 'null'])
df
| ID | A | B | C | D | |
|---|---|---|---|---|---|
| 0 | C1 | 1 | 2 | 3 | 4 |
| 1 | C2 | 5 | 6 | 7 | 8 |
| 2 | C3 | 1 | 3 | 5 | 7 |
pandas DataFrame 만들기
df_1 = pd.DataFrame(data=np.arange(12).reshape(3, 4),
index=['r0', 'r1', 'r2'], # Will default to np.arange(n) if no indexing
columns=['c0', 'c1', 'c2', 'c3'],
dtype='int', # Data type to force, otherwise infer
copy=False) # Copy data from inputs
df_1
| c0 | c1 | c2 | c3 | |
|---|---|---|---|---|
| r0 | 0 | 1 | 2 | 3 |
| r1 | 4 | 5 | 6 | 7 |
| r2 | 8 | 9 | 10 | 11 |
df_1.T
| r0 | r1 | r2 | |
|---|---|---|---|
| c0 | 0 | 4 | 8 |
| c1 | 1 | 5 | 9 |
| c2 | 2 | 6 | 10 |
| c3 | 3 | 7 | 11 |
axes()
# axes : 행과 열 이름을 리스트로 변환
df_1.axes
[Index(['r0', 'r1', 'r2'], dtype='object'),
Index(['c0', 'c1', 'c2', 'c3'], dtype='object')]
dtypes(), shape(), size(), values()
# dtypes : 데이터 형태 반환
# shape : 행과 열의 개수(차원)을 튜플로 반환
# size : NDFrame의 원소의 개수를 반환
# values : NDFrame의 원소를 numpy 형태로 반환
reindex()
# index 재설정하기
new_idx = ['r0', 'r1', 'r2', 'r5', 'r6']
# reindex 과정에서 생긴 결측값 채우기 (fill in missing values) : fill_value
df_1.reindex(new_idx, fill_value=0)
| c0 | c1 | c2 | c3 | |
|---|---|---|---|---|
| r0 | 0 | 1 | 2 | 3 |
| r1 | 4 | 5 | 6 | 7 |
| r2 | 8 | 9 | 10 | 11 |
| r5 | 0 | 0 | 0 | 0 |
| r6 | 0 | 0 | 0 | 0 |
시계열 데이터
- DataFrame의 index만들 때, pd.date_range(date,periods, freq)
date_idx=pd.date_range('2021-08-05', periods=5, freq='D')
date_idx
DatetimeIndex(['2021-08-05', '2021-08-06', '2021-08-07', '2021-08-08',
'2021-08-09'],
dtype='datetime64[ns]', freq='D')
dataframe 데이터 파악하기
-
shape 속성 (row, column)
-
describe 함수 - 숫자형 데이터의 통계치 계산
-
info 함수 - 데이터 타입, 각 아이템의 개수 등 출력
train_data.shape # (891, 12) = 891개의 데이터가 있고 12개의 속성이 있다.
(891, 12)
train_data.describe()
| PassengerId | Survived | Pclass | Age | SibSp | Parch | Fare | |
|---|---|---|---|---|---|---|---|
| count | 891.000000 | 891.000000 | 891.000000 | 714.000000 | 891.000000 | 891.000000 | 891.000000 |
| mean | 446.000000 | 0.383838 | 2.308642 | 29.699118 | 0.523008 | 0.381594 | 32.204208 |
| std | 257.353842 | 0.486592 | 0.836071 | 14.526497 | 1.102743 | 0.806057 | 49.693429 |
| min | 1.000000 | 0.000000 | 1.000000 | 0.420000 | 0.000000 | 0.000000 | 0.000000 |
| 25% | 223.500000 | 0.000000 | 2.000000 | 20.125000 | 0.000000 | 0.000000 | 7.910400 |
| 50% | 446.000000 | 0.000000 | 3.000000 | 28.000000 | 0.000000 | 0.000000 | 14.454200 |
| 75% | 668.500000 | 1.000000 | 3.000000 | 38.000000 | 1.000000 | 0.000000 | 31.000000 |
| max | 891.000000 | 1.000000 | 3.000000 | 80.000000 | 8.000000 | 6.000000 | 512.329200 |
info함수로 각 변수의 데이터 타입 확인
- 타입 변경은 astype함수를 사용
train_data.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 891 entries, 0 to 890
Data columns (total 12 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 PassengerId 891 non-null int64
1 Survived 891 non-null int64
2 Pclass 891 non-null int64
3 Name 891 non-null object
4 Sex 891 non-null object
5 Age 714 non-null float64
6 SibSp 891 non-null int64
7 Parch 891 non-null int64
8 Ticket 891 non-null object
9 Fare 891 non-null float64
10 Cabin 204 non-null object
11 Embarked 889 non-null object
dtypes: float64(2), int64(5), object(5)
memory usage: 83.7+ KB
인덱스(index)
-
index 속성
-
각 아이템을 특정할 수 있는 고유의 값을 저장
-
복잡한 데이터의 경우, 멀티 인덱스로 표현 가능
train_data.index
RangeIndex(start=0, stop=891, step=1)
컬럼(column)
-
columns 속성
-
각각의 특성(feature)을 나타냄
-
복잡한 데이터의 경우, 멀티 컬럼으로 표현 가능
train_data.columns
Index(['PassengerId', 'Survived', 'Pclass', 'Name', 'Sex', 'Age', 'SibSp',
'Parch', 'Ticket', 'Fare', 'Cabin', 'Embarked'],
dtype='object')
read_csv 함수 파라미터
-
sep - 각 데이터 값을 구별하기 위한 구분자(separator) 설정
-
header - header를 무시할 경우, None 설정
-
index_col - index로 사용할 column 설정
-
usecols - 실제로 dataframe에 로딩할 columns만 설정
train_data1 = pd.read_csv('E:\kaggle/titanic/train.csv', index_col='PassengerId', usecols=['PassengerId', 'Survived', 'Pclass', 'Name'])
# index_col = passengerId가 인덱스로 존재 # usecols = 필요한 컴럼만 가져온다.
# index_col = 파일 불러올때 index 지정해주기
train_data1
| Survived | Pclass | Name | |
|---|---|---|---|
| PassengerId | |||
| 1 | 0 | 3 | Braund, Mr. Owen Harris |
| 2 | 1 | 1 | Cumings, Mrs. John Bradley (Florence Briggs Th... |
| 3 | 1 | 3 | Heikkinen, Miss. Laina |
| 4 | 1 | 1 | Futrelle, Mrs. Jacques Heath (Lily May Peel) |
| 5 | 0 | 3 | Allen, Mr. William Henry |
| ... | ... | ... | ... |
| 887 | 0 | 2 | Montvila, Rev. Juozas |
| 888 | 1 | 1 | Graham, Miss. Margaret Edith |
| 889 | 0 | 3 | Johnston, Miss. Catherine Helen "Carrie" |
| 890 | 1 | 1 | Behr, Mr. Karl Howell |
| 891 | 0 | 3 | Dooley, Mr. Patrick |
891 rows × 3 columns
하나의 컬럼 선택하기
train_data['Survived'] # 특정 컬럼만 series로 가져온다.
0 0
1 1
2 1
3 1
4 0
..
886 0
887 1
888 0
889 1
890 0
Name: Survived, Length: 891, dtype: int64
복수의 컬럼 선택하기
train_data[['Survived', 'Name', 'Age', 'Embarked']]
| Survived | Name | Age | Embarked | |
|---|---|---|---|---|
| 0 | 0 | Braund, Mr. Owen Harris | 22.0 | S |
| 1 | 1 | Cumings, Mrs. John Bradley (Florence Briggs Th... | 38.0 | C |
| 2 | 1 | Heikkinen, Miss. Laina | 26.0 | S |
| 3 | 1 | Futrelle, Mrs. Jacques Heath (Lily May Peel) | 35.0 | S |
| 4 | 0 | Allen, Mr. William Henry | 35.0 | S |
| ... | ... | ... | ... | ... |
| 886 | 0 | Montvila, Rev. Juozas | 27.0 | S |
| 887 | 1 | Graham, Miss. Margaret Edith | 19.0 | S |
| 888 | 0 | Johnston, Miss. Catherine Helen "Carrie" | NaN | S |
| 889 | 1 | Behr, Mr. Karl Howell | 26.0 | C |
| 890 | 0 | Dooley, Mr. Patrick | 32.0 | Q |
891 rows × 4 columns
train_data[['Survived']] #이건 데이터 프레임으로 가져온다.
| Survived | |
|---|---|
| 0 | 0 |
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 4 | 0 |
| ... | ... |
| 886 | 0 |
| 887 | 1 |
| 888 | 0 |
| 889 | 1 |
| 890 | 0 |
891 rows × 1 columns
dataframe slicing
-
dataframe의 경우 기본적으로 [] 연산자가 column 선택에 사용
-
하지만, slicing은 row 레벨로 지원
train_data[7:10] # 슬라이싱은 row로 적용 # 슬라이싱만 예외
| PassengerId | Survived | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 7 | 8 | 0 | 3 | Palsson, Master. Gosta Leonard | male | 2.0 | 3 | 1 | 349909 | 21.0750 | NaN | S |
| 8 | 9 | 1 | 3 | Johnson, Mrs. Oscar W (Elisabeth Vilhelmina Berg) | female | 27.0 | 0 | 2 | 347742 | 11.1333 | NaN | S |
| 9 | 10 | 1 | 2 | Nasser, Mrs. Nicholas (Adele Achem) | female | 14.0 | 1 | 0 | 237736 | 30.0708 | NaN | C |
row 선택하기
-
Seires의 경우 []로 row 선택이 가능하나, DataFrame의 경우는 기본적으로 column을 선택하도록 설계
-
.loc, .iloc로 row 선택 가능
-
loc - 인덱스 자체를 사용
-
iloc - 0 based index로 사용
-
이 두 함수는 ,를 사용하여 column 선택도 가능
-
train_data.index = np.arange(100, 991)
train_data.loc[986] # 존재하는 index를 가져옴
PassengerId 887
Survived 0
Pclass 2
Name Montvila, Rev. Juozas
Sex male
Age 27
SibSp 0
Parch 0
Ticket 211536
Fare 13
Cabin NaN
Embarked S
Name: 986, dtype: object
train_data.loc[[986, 100, 110, 990]]
| PassengerId | Survived | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 986 | 887 | 0 | 2 | Montvila, Rev. Juozas | male | 27.0 | 0 | 0 | 211536 | 13.00 | NaN | S |
| 100 | 1 | 0 | 3 | Braund, Mr. Owen Harris | male | 22.0 | 1 | 0 | A/5 21171 | 7.25 | NaN | S |
| 110 | 11 | 1 | 3 | Sandstrom, Miss. Marguerite Rut | female | 4.0 | 1 | 1 | PP 9549 | 16.70 | G6 | S |
| 990 | 891 | 0 | 3 | Dooley, Mr. Patrick | male | 32.0 | 0 | 0 | 370376 | 7.75 | NaN | Q |
train_data.iloc[[0, 100, 200, 2]]
# index 관계없이 0부터 시작하는 index base를 가져옴
| PassengerId | Survived | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 100 | 1 | 0 | 3 | Braund, Mr. Owen Harris | male | 22.0 | 1 | 0 | A/5 21171 | 7.2500 | NaN | S |
| 200 | 101 | 0 | 3 | Petranec, Miss. Matilda | female | 28.0 | 0 | 0 | 349245 | 7.8958 | NaN | S |
| 300 | 201 | 0 | 3 | Vande Walle, Mr. Nestor Cyriel | male | 28.0 | 0 | 0 | 345770 | 9.5000 | NaN | S |
| 102 | 3 | 1 | 3 | Heikkinen, Miss. Laina | female | 26.0 | 0 | 0 | STON/O2. 3101282 | 7.9250 | NaN | S |
row, column 동시에 선택하기
- loc, iloc 속성을 이용할 때, 콤마를 이용하여 둘 다 명시 가능
train_data.loc[[986, 100, 110, 990], ['Survived', 'Name', 'Sex', 'Age']]
# loc = location
| Survived | Name | Sex | Age | |
|---|---|---|---|---|
| 986 | 0 | Montvila, Rev. Juozas | male | 27.0 |
| 100 | 0 | Braund, Mr. Owen Harris | male | 22.0 |
| 110 | 1 | Sandstrom, Miss. Marguerite Rut | female | 4.0 |
| 990 | 0 | Dooley, Mr. Patrick | male | 32.0 |
train_data.iloc[[101, 100, 200, 102], [1, 4, 5]] # columns 역시 0베이스부터 시작
| Survived | Sex | Age | |
|---|---|---|---|
| 201 | 0 | male | NaN |
| 200 | 0 | female | 28.0 |
| 300 | 0 | male | 28.0 |
| 202 | 0 | male | 21.0 |
train_data = pd.read_csv('E:\kaggle/titanic/train.csv')
boolean selection으로 row 선택하기
- numpy에서와 동일한 방식으로 해당 조건에 맞는 row만 선택
30대이면서 1등석에 탄 사람 선택하기
class_ = train_data['Pclass'] == 1
age_ = (train_data['Age'] >= 30) & (train_data['Age'] < 40)
train_data[class_ & age_]
| PassengerId | Survived | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | 2 | 1 | 1 | Cumings, Mrs. John Bradley (Florence Briggs Th... | female | 38.0 | 1 | 0 | PC 17599 | 71.2833 | C85 | C |
| 3 | 4 | 1 | 1 | Futrelle, Mrs. Jacques Heath (Lily May Peel) | female | 35.0 | 1 | 0 | 113803 | 53.1000 | C123 | S |
| 61 | 62 | 1 | 1 | Icard, Miss. Amelie | female | 38.0 | 0 | 0 | 113572 | 80.0000 | B28 | NaN |
| 137 | 138 | 0 | 1 | Futrelle, Mr. Jacques Heath | male | 37.0 | 1 | 0 | 113803 | 53.1000 | C123 | S |
| 215 | 216 | 1 | 1 | Newell, Miss. Madeleine | female | 31.0 | 1 | 0 | 35273 | 113.2750 | D36 | C |
| 218 | 219 | 1 | 1 | Bazzani, Miss. Albina | female | 32.0 | 0 | 0 | 11813 | 76.2917 | D15 | C |
| 224 | 225 | 1 | 1 | Hoyt, Mr. Frederick Maxfield | male | 38.0 | 1 | 0 | 19943 | 90.0000 | C93 | S |
| 230 | 231 | 1 | 1 | Harris, Mrs. Henry Birkhardt (Irene Wallach) | female | 35.0 | 1 | 0 | 36973 | 83.4750 | C83 | S |
| 248 | 249 | 1 | 1 | Beckwith, Mr. Richard Leonard | male | 37.0 | 1 | 1 | 11751 | 52.5542 | D35 | S |
| 257 | 258 | 1 | 1 | Cherry, Miss. Gladys | female | 30.0 | 0 | 0 | 110152 | 86.5000 | B77 | S |
| 258 | 259 | 1 | 1 | Ward, Miss. Anna | female | 35.0 | 0 | 0 | PC 17755 | 512.3292 | NaN | C |
| 269 | 270 | 1 | 1 | Bissette, Miss. Amelia | female | 35.0 | 0 | 0 | PC 17760 | 135.6333 | C99 | S |
| 273 | 274 | 0 | 1 | Natsch, Mr. Charles H | male | 37.0 | 0 | 1 | PC 17596 | 29.7000 | C118 | C |
| 309 | 310 | 1 | 1 | Francatelli, Miss. Laura Mabel | female | 30.0 | 0 | 0 | PC 17485 | 56.9292 | E36 | C |
| 318 | 319 | 1 | 1 | Wick, Miss. Mary Natalie | female | 31.0 | 0 | 2 | 36928 | 164.8667 | C7 | S |
| 325 | 326 | 1 | 1 | Young, Miss. Marie Grice | female | 36.0 | 0 | 0 | PC 17760 | 135.6333 | C32 | C |
| 332 | 333 | 0 | 1 | Graham, Mr. George Edward | male | 38.0 | 0 | 1 | PC 17582 | 153.4625 | C91 | S |
| 383 | 384 | 1 | 1 | Holverson, Mrs. Alexander Oskar (Mary Aline To... | female | 35.0 | 1 | 0 | 113789 | 52.0000 | NaN | S |
| 390 | 391 | 1 | 1 | Carter, Mr. William Ernest | male | 36.0 | 1 | 2 | 113760 | 120.0000 | B96 B98 | S |
| 412 | 413 | 1 | 1 | Minahan, Miss. Daisy E | female | 33.0 | 1 | 0 | 19928 | 90.0000 | C78 | Q |
| 447 | 448 | 1 | 1 | Seward, Mr. Frederic Kimber | male | 34.0 | 0 | 0 | 113794 | 26.5500 | NaN | S |
| 452 | 453 | 0 | 1 | Foreman, Mr. Benjamin Laventall | male | 30.0 | 0 | 0 | 113051 | 27.7500 | C111 | C |
| 486 | 487 | 1 | 1 | Hoyt, Mrs. Frederick Maxfield (Jane Anne Forby) | female | 35.0 | 1 | 0 | 19943 | 90.0000 | C93 | S |
| 512 | 513 | 1 | 1 | McGough, Mr. James Robert | male | 36.0 | 0 | 0 | PC 17473 | 26.2875 | E25 | S |
| 520 | 521 | 1 | 1 | Perreault, Miss. Anne | female | 30.0 | 0 | 0 | 12749 | 93.5000 | B73 | S |
| 537 | 538 | 1 | 1 | LeRoy, Miss. Bertha | female | 30.0 | 0 | 0 | PC 17761 | 106.4250 | NaN | C |
| 540 | 541 | 1 | 1 | Crosby, Miss. Harriet R | female | 36.0 | 0 | 2 | WE/P 5735 | 71.0000 | B22 | S |
| 558 | 559 | 1 | 1 | Taussig, Mrs. Emil (Tillie Mandelbaum) | female | 39.0 | 1 | 1 | 110413 | 79.6500 | E67 | S |
| 572 | 573 | 1 | 1 | Flynn, Mr. John Irwin ("Irving") | male | 36.0 | 0 | 0 | PC 17474 | 26.3875 | E25 | S |
| 577 | 578 | 1 | 1 | Silvey, Mrs. William Baird (Alice Munger) | female | 39.0 | 1 | 0 | 13507 | 55.9000 | E44 | S |
| 581 | 582 | 1 | 1 | Thayer, Mrs. John Borland (Marian Longstreth M... | female | 39.0 | 1 | 1 | 17421 | 110.8833 | C68 | C |
| 583 | 584 | 0 | 1 | Ross, Mr. John Hugo | male | 36.0 | 0 | 0 | 13049 | 40.1250 | A10 | C |
| 604 | 605 | 1 | 1 | Homer, Mr. Harry ("Mr E Haven") | male | 35.0 | 0 | 0 | 111426 | 26.5500 | NaN | C |
| 632 | 633 | 1 | 1 | Stahelin-Maeglin, Dr. Max | male | 32.0 | 0 | 0 | 13214 | 30.5000 | B50 | C |
| 671 | 672 | 0 | 1 | Davidson, Mr. Thornton | male | 31.0 | 1 | 0 | F.C. 12750 | 52.0000 | B71 | S |
| 679 | 680 | 1 | 1 | Cardeza, Mr. Thomas Drake Martinez | male | 36.0 | 0 | 1 | PC 17755 | 512.3292 | B51 B53 B55 | C |
| 690 | 691 | 1 | 1 | Dick, Mr. Albert Adrian | male | 31.0 | 1 | 0 | 17474 | 57.0000 | B20 | S |
| 701 | 702 | 1 | 1 | Silverthorne, Mr. Spencer Victor | male | 35.0 | 0 | 0 | PC 17475 | 26.2875 | E24 | S |
| 716 | 717 | 1 | 1 | Endres, Miss. Caroline Louise | female | 38.0 | 0 | 0 | PC 17757 | 227.5250 | C45 | C |
| 737 | 738 | 1 | 1 | Lesurer, Mr. Gustave J | male | 35.0 | 0 | 0 | PC 17755 | 512.3292 | B101 | C |
| 741 | 742 | 0 | 1 | Cavendish, Mr. Tyrell William | male | 36.0 | 1 | 0 | 19877 | 78.8500 | C46 | S |
| 759 | 760 | 1 | 1 | Rothes, the Countess. of (Lucy Noel Martha Dye... | female | 33.0 | 0 | 0 | 110152 | 86.5000 | B77 | S |
| 763 | 764 | 1 | 1 | Carter, Mrs. William Ernest (Lucile Polk) | female | 36.0 | 1 | 2 | 113760 | 120.0000 | B96 B98 | S |
| 806 | 807 | 0 | 1 | Andrews, Mr. Thomas Jr | male | 39.0 | 0 | 0 | 112050 | 0.0000 | A36 | S |
| 809 | 810 | 1 | 1 | Chambers, Mrs. Norman Campbell (Bertha Griggs) | female | 33.0 | 1 | 0 | 113806 | 53.1000 | E8 | S |
| 822 | 823 | 0 | 1 | Reuchlin, Jonkheer. John George | male | 38.0 | 0 | 0 | 19972 | 0.0000 | NaN | S |
| 835 | 836 | 1 | 1 | Compton, Miss. Sara Rebecca | female | 39.0 | 1 | 1 | PC 17756 | 83.1583 | E49 | C |
| 842 | 843 | 1 | 1 | Serepeca, Miss. Augusta | female | 30.0 | 0 | 0 | 113798 | 31.0000 | NaN | C |
| 867 | 868 | 0 | 1 | Roebling, Mr. Washington Augustus II | male | 31.0 | 0 | 0 | PC 17590 | 50.4958 | A24 | S |
| 872 | 873 | 0 | 1 | Carlsson, Mr. Frans Olof | male | 33.0 | 0 | 0 | 695 | 5.0000 | B51 B53 B55 | S |
새 column 추가하기
-
[] 사용하여 추가하기
-
insert 함수 사용하여 원하는 위치에 추가하기
train_data['Age_double'] = train_data['Age'] * 2
train_data.head()
| PassengerId | Survived | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked | Age_double | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 0 | 3 | Braund, Mr. Owen Harris | male | 22.0 | 1 | 0 | A/5 21171 | 7.2500 | NaN | S | 44.0 |
| 1 | 2 | 1 | 1 | Cumings, Mrs. John Bradley (Florence Briggs Th... | female | 38.0 | 1 | 0 | PC 17599 | 71.2833 | C85 | C | 76.0 |
| 2 | 3 | 1 | 3 | Heikkinen, Miss. Laina | female | 26.0 | 0 | 0 | STON/O2. 3101282 | 7.9250 | NaN | S | 52.0 |
| 3 | 4 | 1 | 1 | Futrelle, Mrs. Jacques Heath (Lily May Peel) | female | 35.0 | 1 | 0 | 113803 | 53.1000 | C123 | S | 70.0 |
| 4 | 5 | 0 | 3 | Allen, Mr. William Henry | male | 35.0 | 0 | 0 | 373450 | 8.0500 | NaN | S | 70.0 |
train_data['Age_tripple'] = train_data['Age_double'] + train_data['Age']
train_data.head()
| PassengerId | Survived | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked | Age_double | Age_tripple | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 0 | 3 | Braund, Mr. Owen Harris | male | 22.0 | 1 | 0 | A/5 21171 | 7.2500 | NaN | S | 44.0 | 66.0 |
| 1 | 2 | 1 | 1 | Cumings, Mrs. John Bradley (Florence Briggs Th... | female | 38.0 | 1 | 0 | PC 17599 | 71.2833 | C85 | C | 76.0 | 114.0 |
| 2 | 3 | 1 | 3 | Heikkinen, Miss. Laina | female | 26.0 | 0 | 0 | STON/O2. 3101282 | 7.9250 | NaN | S | 52.0 | 78.0 |
| 3 | 4 | 1 | 1 | Futrelle, Mrs. Jacques Heath (Lily May Peel) | female | 35.0 | 1 | 0 | 113803 | 53.1000 | C123 | S | 70.0 | 105.0 |
| 4 | 5 | 0 | 3 | Allen, Mr. William Henry | male | 35.0 | 0 | 0 | 373450 | 8.0500 | NaN | S | 70.0 | 105.0 |
train_data.insert(3, 'Fare10', train_data['Fare'] / 10) # insert : 특정 열에 넣기
train_data.head()
| PassengerId | Survived | Pclass | Fare10 | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked | Age_double | Age_tripple | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 0 | 3 | 0.72500 | Braund, Mr. Owen Harris | male | 22.0 | 1 | 0 | A/5 21171 | 7.2500 | NaN | S | 44.0 | 66.0 |
| 1 | 2 | 1 | 1 | 7.12833 | Cumings, Mrs. John Bradley (Florence Briggs Th... | female | 38.0 | 1 | 0 | PC 17599 | 71.2833 | C85 | C | 76.0 | 114.0 |
| 2 | 3 | 1 | 3 | 0.79250 | Heikkinen, Miss. Laina | female | 26.0 | 0 | 0 | STON/O2. 3101282 | 7.9250 | NaN | S | 52.0 | 78.0 |
| 3 | 4 | 1 | 1 | 5.31000 | Futrelle, Mrs. Jacques Heath (Lily May Peel) | female | 35.0 | 1 | 0 | 113803 | 53.1000 | C123 | S | 70.0 | 105.0 |
| 4 | 5 | 0 | 3 | 0.80500 | Allen, Mr. William Henry | male | 35.0 | 0 | 0 | 373450 | 8.0500 | NaN | S | 70.0 | 105.0 |
column 삭제하기
-
drop 함수 사용하여 삭제
- 리스트를 사용하여 멀티플 삭제 가능
train_data.drop('Age_tripple', axis=1) # axis =0 은 행레벨, 1은 열레벨
train_data.head()
# 보면 알겠지만 대부분의 함수들은 복사본에 적용. 원본 데이터는 건들지 않는다.
| PassengerId | Survived | Pclass | Fare10 | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked | Age_double | Age_tripple | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 0 | 3 | 0.72500 | Braund, Mr. Owen Harris | male | 22.0 | 1 | 0 | A/5 21171 | 7.2500 | NaN | S | 44.0 | 66.0 |
| 1 | 2 | 1 | 1 | 7.12833 | Cumings, Mrs. John Bradley (Florence Briggs Th... | female | 38.0 | 1 | 0 | PC 17599 | 71.2833 | C85 | C | 76.0 | 114.0 |
| 2 | 3 | 1 | 3 | 0.79250 | Heikkinen, Miss. Laina | female | 26.0 | 0 | 0 | STON/O2. 3101282 | 7.9250 | NaN | S | 52.0 | 78.0 |
| 3 | 4 | 1 | 1 | 5.31000 | Futrelle, Mrs. Jacques Heath (Lily May Peel) | female | 35.0 | 1 | 0 | 113803 | 53.1000 | C123 | S | 70.0 | 105.0 |
| 4 | 5 | 0 | 3 | 0.80500 | Allen, Mr. William Henry | male | 35.0 | 0 | 0 | 373450 | 8.0500 | NaN | S | 70.0 | 105.0 |
train_data.drop(['Age_double', 'Age_tripple'], axis=1)
| PassengerId | Survived | Pclass | Fare10 | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 0 | 3 | 0.72500 | Braund, Mr. Owen Harris | male | 22.0 | 1 | 0 | A/5 21171 | 7.2500 | NaN | S |
| 1 | 2 | 1 | 1 | 7.12833 | Cumings, Mrs. John Bradley (Florence Briggs Th... | female | 38.0 | 1 | 0 | PC 17599 | 71.2833 | C85 | C |
| 2 | 3 | 1 | 3 | 0.79250 | Heikkinen, Miss. Laina | female | 26.0 | 0 | 0 | STON/O2. 3101282 | 7.9250 | NaN | S |
| 3 | 4 | 1 | 1 | 5.31000 | Futrelle, Mrs. Jacques Heath (Lily May Peel) | female | 35.0 | 1 | 0 | 113803 | 53.1000 | C123 | S |
| 4 | 5 | 0 | 3 | 0.80500 | Allen, Mr. William Henry | male | 35.0 | 0 | 0 | 373450 | 8.0500 | NaN | S |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 886 | 887 | 0 | 2 | 1.30000 | Montvila, Rev. Juozas | male | 27.0 | 0 | 0 | 211536 | 13.0000 | NaN | S |
| 887 | 888 | 1 | 1 | 3.00000 | Graham, Miss. Margaret Edith | female | 19.0 | 0 | 0 | 112053 | 30.0000 | B42 | S |
| 888 | 889 | 0 | 3 | 2.34500 | Johnston, Miss. Catherine Helen "Carrie" | female | NaN | 1 | 2 | W./C. 6607 | 23.4500 | NaN | S |
| 889 | 890 | 1 | 1 | 3.00000 | Behr, Mr. Karl Howell | male | 26.0 | 0 | 0 | 111369 | 30.0000 | C148 | C |
| 890 | 891 | 0 | 3 | 0.77500 | Dooley, Mr. Patrick | male | 32.0 | 0 | 0 | 370376 | 7.7500 | NaN | Q |
891 rows × 13 columns
train_data.drop(['Age_double', 'Age_tripple'], axis=1, inplace=True)
# inplace하면 원본에 저장
train_data
| PassengerId | Survived | Pclass | Fare10 | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 0 | 3 | 0.72500 | Braund, Mr. Owen Harris | male | 22.0 | 1 | 0 | A/5 21171 | 7.2500 | NaN | S |
| 1 | 2 | 1 | 1 | 7.12833 | Cumings, Mrs. John Bradley (Florence Briggs Th... | female | 38.0 | 1 | 0 | PC 17599 | 71.2833 | C85 | C |
| 2 | 3 | 1 | 3 | 0.79250 | Heikkinen, Miss. Laina | female | 26.0 | 0 | 0 | STON/O2. 3101282 | 7.9250 | NaN | S |
| 3 | 4 | 1 | 1 | 5.31000 | Futrelle, Mrs. Jacques Heath (Lily May Peel) | female | 35.0 | 1 | 0 | 113803 | 53.1000 | C123 | S |
| 4 | 5 | 0 | 3 | 0.80500 | Allen, Mr. William Henry | male | 35.0 | 0 | 0 | 373450 | 8.0500 | NaN | S |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 886 | 887 | 0 | 2 | 1.30000 | Montvila, Rev. Juozas | male | 27.0 | 0 | 0 | 211536 | 13.0000 | NaN | S |
| 887 | 888 | 1 | 1 | 3.00000 | Graham, Miss. Margaret Edith | female | 19.0 | 0 | 0 | 112053 | 30.0000 | B42 | S |
| 888 | 889 | 0 | 3 | 2.34500 | Johnston, Miss. Catherine Helen "Carrie" | female | NaN | 1 | 2 | W./C. 6607 | 23.4500 | NaN | S |
| 889 | 890 | 1 | 1 | 3.00000 | Behr, Mr. Karl Howell | male | 26.0 | 0 | 0 | 111369 | 30.0000 | C148 | C |
| 890 | 891 | 0 | 3 | 0.77500 | Dooley, Mr. Patrick | male | 32.0 | 0 | 0 | 370376 | 7.7500 | NaN | Q |
891 rows × 13 columns
변수의 상관관계
- 이 두변수간의 흐름이 얼마나 비슷한가를 나타내는 척도 (증가, 감소) 그 폭이 얼마나 비슷하냐
- 두 변수간의 패턴을 본다.
- 인과관계는 일수도 있고 아닐 수도 있다.
train_data = pd.read_csv('F:/data/titanic/train.csv')
train_data.head()
| PassengerId | Survived | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 0 | 3 | Braund, Mr. Owen Harris | male | 22.0 | 1 | 0 | A/5 21171 | 7.2500 | NaN | S |
| 1 | 2 | 1 | 1 | Cumings, Mrs. John Bradley (Florence Briggs Th... | female | 38.0 | 1 | 0 | PC 17599 | 71.2833 | C85 | C |
| 2 | 3 | 1 | 3 | Heikkinen, Miss. Laina | female | 26.0 | 0 | 0 | STON/O2. 3101282 | 7.9250 | NaN | S |
| 3 | 4 | 1 | 1 | Futrelle, Mrs. Jacques Heath (Lily May Peel) | female | 35.0 | 1 | 0 | 113803 | 53.1000 | C123 | S |
| 4 | 5 | 0 | 3 | Allen, Mr. William Henry | male | 35.0 | 0 | 0 | 373450 | 8.0500 | NaN | S |
변수(column) 사이의 상관계수(correlation)
-
corr함수를 통해 상관계수 연산 (-1, 1 사이의 결과)
-
연속성(숫자형)데이터에 대해서만 연산
-
인과관계를 의미하진 않음
-
train_data.corr()
| PassengerId | Survived | Pclass | Age | SibSp | Parch | Fare | |
|---|---|---|---|---|---|---|---|
| PassengerId | 1.000000 | -0.005007 | -0.035144 | 0.036847 | -0.057527 | -0.001652 | 0.012658 |
| Survived | -0.005007 | 1.000000 | -0.338481 | -0.077221 | -0.035322 | 0.081629 | 0.257307 |
| Pclass | -0.035144 | -0.338481 | 1.000000 | -0.369226 | 0.083081 | 0.018443 | -0.549500 |
| Age | 0.036847 | -0.077221 | -0.369226 | 1.000000 | -0.308247 | -0.189119 | 0.096067 |
| SibSp | -0.057527 | -0.035322 | 0.083081 | -0.308247 | 1.000000 | 0.414838 | 0.159651 |
| Parch | -0.001652 | 0.081629 | 0.018443 | -0.189119 | 0.414838 | 1.000000 | 0.216225 |
| Fare | 0.012658 | 0.257307 | -0.549500 | 0.096067 | 0.159651 | 0.216225 | 1.000000 |
plt.matshow(train_data.corr()) #색깔이 밝을수록 관련이 깊다.

train_data.isna() # True인 경우 NaN이다.
| PassengerId | Survived | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | False | False | False | False | False | False | False | False | False | False | True | False |
| 1 | False | False | False | False | False | False | False | False | False | False | False | False |
| 2 | False | False | False | False | False | False | False | False | False | False | True | False |
| 3 | False | False | False | False | False | False | False | False | False | False | False | False |
| 4 | False | False | False | False | False | False | False | False | False | False | True | False |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 886 | False | False | False | False | False | False | False | False | False | False | True | False |
| 887 | False | False | False | False | False | False | False | False | False | False | False | False |
| 888 | False | False | False | False | False | True | False | False | False | False | True | False |
| 889 | False | False | False | False | False | False | False | False | False | False | False | False |
| 890 | False | False | False | False | False | False | False | False | False | False | True | False |
891 rows × 12 columns
train_data['Age'].isna()
0 False
1 False
2 False
3 False
4 False
...
886 False
887 False
888 True
889 False
890 False
Name: Age, Length: 891, dtype: bool
NaN 처리 방법
-
데이터에서 삭제
- dropna 함수
-
다른 값으로 치환
- fillna 함수
-
NaN 데이터 삭제하기
train_data.dropna() # 한개라도 NaN이 있다면 그 row를 지워버린다.
| PassengerId | Survived | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | 2 | 1 | 1 | Cumings, Mrs. John Bradley (Florence Briggs Th... | female | 38.0 | 1 | 0 | PC 17599 | 71.2833 | C85 | C |
| 3 | 4 | 1 | 1 | Futrelle, Mrs. Jacques Heath (Lily May Peel) | female | 35.0 | 1 | 0 | 113803 | 53.1000 | C123 | S |
| 6 | 7 | 0 | 1 | McCarthy, Mr. Timothy J | male | 54.0 | 0 | 0 | 17463 | 51.8625 | E46 | S |
| 10 | 11 | 1 | 3 | Sandstrom, Miss. Marguerite Rut | female | 4.0 | 1 | 1 | PP 9549 | 16.7000 | G6 | S |
| 11 | 12 | 1 | 1 | Bonnell, Miss. Elizabeth | female | 58.0 | 0 | 0 | 113783 | 26.5500 | C103 | S |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 871 | 872 | 1 | 1 | Beckwith, Mrs. Richard Leonard (Sallie Monypeny) | female | 47.0 | 1 | 1 | 11751 | 52.5542 | D35 | S |
| 872 | 873 | 0 | 1 | Carlsson, Mr. Frans Olof | male | 33.0 | 0 | 0 | 695 | 5.0000 | B51 B53 B55 | S |
| 879 | 880 | 1 | 1 | Potter, Mrs. Thomas Jr (Lily Alexenia Wilson) | female | 56.0 | 0 | 1 | 11767 | 83.1583 | C50 | C |
| 887 | 888 | 1 | 1 | Graham, Miss. Margaret Edith | female | 19.0 | 0 | 0 | 112053 | 30.0000 | B42 | S |
| 889 | 890 | 1 | 1 | Behr, Mr. Karl Howell | male | 26.0 | 0 | 0 | 111369 | 30.0000 | C148 | C |
183 rows × 12 columns
train_data.dropna(subset=['Age', 'Cabin']) # subset : 특정 열의 NaN만 판단
| PassengerId | Survived | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | 2 | 1 | 1 | Cumings, Mrs. John Bradley (Florence Briggs Th... | female | 38.0 | 1 | 0 | PC 17599 | 71.2833 | C85 | C |
| 3 | 4 | 1 | 1 | Futrelle, Mrs. Jacques Heath (Lily May Peel) | female | 35.0 | 1 | 0 | 113803 | 53.1000 | C123 | S |
| 6 | 7 | 0 | 1 | McCarthy, Mr. Timothy J | male | 54.0 | 0 | 0 | 17463 | 51.8625 | E46 | S |
| 10 | 11 | 1 | 3 | Sandstrom, Miss. Marguerite Rut | female | 4.0 | 1 | 1 | PP 9549 | 16.7000 | G6 | S |
| 11 | 12 | 1 | 1 | Bonnell, Miss. Elizabeth | female | 58.0 | 0 | 0 | 113783 | 26.5500 | C103 | S |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 871 | 872 | 1 | 1 | Beckwith, Mrs. Richard Leonard (Sallie Monypeny) | female | 47.0 | 1 | 1 | 11751 | 52.5542 | D35 | S |
| 872 | 873 | 0 | 1 | Carlsson, Mr. Frans Olof | male | 33.0 | 0 | 0 | 695 | 5.0000 | B51 B53 B55 | S |
| 879 | 880 | 1 | 1 | Potter, Mrs. Thomas Jr (Lily Alexenia Wilson) | female | 56.0 | 0 | 1 | 11767 | 83.1583 | C50 | C |
| 887 | 888 | 1 | 1 | Graham, Miss. Margaret Edith | female | 19.0 | 0 | 0 | 112053 | 30.0000 | B42 | S |
| 889 | 890 | 1 | 1 | Behr, Mr. Karl Howell | male | 26.0 | 0 | 0 | 111369 | 30.0000 | C148 | C |
185 rows × 12 columns
train_data.dropna(axis=1) # 컬럼 중에 NaN이 있다면 지워버려라
| PassengerId | Survived | Pclass | Name | Sex | SibSp | Parch | Ticket | Fare | |
|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 0 | 3 | Braund, Mr. Owen Harris | male | 1 | 0 | A/5 21171 | 7.2500 |
| 1 | 2 | 1 | 1 | Cumings, Mrs. John Bradley (Florence Briggs Th... | female | 1 | 0 | PC 17599 | 71.2833 |
| 2 | 3 | 1 | 3 | Heikkinen, Miss. Laina | female | 0 | 0 | STON/O2. 3101282 | 7.9250 |
| 3 | 4 | 1 | 1 | Futrelle, Mrs. Jacques Heath (Lily May Peel) | female | 1 | 0 | 113803 | 53.1000 |
| 4 | 5 | 0 | 3 | Allen, Mr. William Henry | male | 0 | 0 | 373450 | 8.0500 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 886 | 887 | 0 | 2 | Montvila, Rev. Juozas | male | 0 | 0 | 211536 | 13.0000 |
| 887 | 888 | 1 | 1 | Graham, Miss. Margaret Edith | female | 0 | 0 | 112053 | 30.0000 |
| 888 | 889 | 0 | 3 | Johnston, Miss. Catherine Helen "Carrie" | female | 1 | 2 | W./C. 6607 | 23.4500 |
| 889 | 890 | 1 | 1 | Behr, Mr. Karl Howell | male | 0 | 0 | 111369 | 30.0000 |
| 890 | 891 | 0 | 3 | Dooley, Mr. Patrick | male | 0 | 0 | 370376 | 7.7500 |
891 rows × 9 columns
NaN 값 대체하기
-
평균으로 대체하기
-
생존자/사망자 별 평균으로 대체하기
train_data['Age'].fillna(train_data['Age'].mean())
#평균을 구하고 결측값에 넣는다.
# # inplace=False : 결과 반환 # inplace=True : 원본 데이터에 적용
0 22.000000
1 38.000000
2 26.000000
3 35.000000
4 35.000000
...
886 27.000000
887 19.000000
888 29.699118
889 26.000000
890 32.000000
Name: Age, Length: 891, dtype: float64
# 생존자 나이 평균
mean1 = train_data[train_data['Survived'] == 1]['Age'].mean()
# 사망자 나이 평균
mean0 = train_data[train_data['Survived'] == 0]['Age'].mean()
print(mean1, mean0)
28.343689655172415 30.62617924528302
train_data[train_data['Survived'] == 1]['Age'].fillna(mean1)
train_data[train_data['Survived'] == 0]['Age'].fillna(mean0)
0 22.000000
4 35.000000
5 30.626179
6 54.000000
7 2.000000
...
884 25.000000
885 39.000000
886 27.000000
888 30.626179
890 32.000000
Name: Age, Length: 549, dtype: float64
train_data.loc[train_data['Survived'] == 1, 'Age'] = train_data[train_data['Survived'] == 1]['Age'].fillna(mean1)
train_data.loc[train_data['Survived'] == 0, 'Age'] = train_data[train_data['Survived'] == 0]['Age'].fillna(mean0)
train_data = pd.read_csv('E:\kaggle/titanic/train.csv')
# numpy와 pandas를 쓸때는 최대한 loop를 지양해야 한다.
Pclass 변수 변환하기
- astype 사용하여 간단히 타입만 변환
train_data['Pclass'] = train_data['Pclass'].astype(str)
Age 변수 변환하기
- 변환 로직을 함수로 만든 후, apply 함수로 적용
def age_categorize(age): #연령대별로 나타내기
if math.isnan(age):
return -1
return math.floor(age / 10) * 10
train_data['Age'].apply(age_categorize)
# apply변수는 해당 컬럼의 모든 값에 다 적용시켜준다.
0 20
1 30
2 20
3 30
4 30
..
886 20
887 10
888 -1
889 20
890 30
Name: Age, Length: 891, dtype: int64
One-hot encoding
-
범주형 데이터는 분석단계에서 계산이 어렵기 때문에 숫자형으로 변경이 필요함
-
범주형 데이터의 각 범주(category)를 column레벨로 변경
-
해당 범주에 해당하면 1, 아니면 0으로 채우는 인코딩 기법
-
pandas.get_dummies 함수 사용
- drop_first : 첫번째 카테고리 값은 사용하지 않음
pd.get_dummies(train_data, columns=['Pclass', 'Sex', 'Embarked'], drop_first=False)
# columns : 바꾸고자 하는 컬럼만
| PassengerId | Survived | Name | Age | SibSp | Parch | Ticket | Fare | Cabin | Pclass_1 | Pclass_2 | Pclass_3 | Sex_female | Sex_male | Embarked_C | Embarked_Q | Embarked_S | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 0 | Braund, Mr. Owen Harris | 22.0 | 1 | 0 | A/5 21171 | 7.2500 | NaN | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 1 |
| 1 | 2 | 1 | Cumings, Mrs. John Bradley (Florence Briggs Th... | 38.0 | 1 | 0 | PC 17599 | 71.2833 | C85 | 1 | 0 | 0 | 1 | 0 | 1 | 0 | 0 |
| 2 | 3 | 1 | Heikkinen, Miss. Laina | 26.0 | 0 | 0 | STON/O2. 3101282 | 7.9250 | NaN | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 1 |
| 3 | 4 | 1 | Futrelle, Mrs. Jacques Heath (Lily May Peel) | 35.0 | 1 | 0 | 113803 | 53.1000 | C123 | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 1 |
| 4 | 5 | 0 | Allen, Mr. William Henry | 35.0 | 0 | 0 | 373450 | 8.0500 | NaN | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 1 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 886 | 887 | 0 | Montvila, Rev. Juozas | 27.0 | 0 | 0 | 211536 | 13.0000 | NaN | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 1 |
| 887 | 888 | 1 | Graham, Miss. Margaret Edith | 19.0 | 0 | 0 | 112053 | 30.0000 | B42 | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 1 |
| 888 | 889 | 0 | Johnston, Miss. Catherine Helen "Carrie" | NaN | 1 | 2 | W./C. 6607 | 23.4500 | NaN | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 1 |
| 889 | 890 | 1 | Behr, Mr. Karl Howell | 26.0 | 0 | 0 | 111369 | 30.0000 | C148 | 1 | 0 | 0 | 0 | 1 | 1 | 0 | 0 |
| 890 | 891 | 0 | Dooley, Mr. Patrick | 32.0 | 0 | 0 | 370376 | 7.7500 | NaN | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 0 |
891 rows × 17 columns
pd.get_dummies(train_data, columns=['Pclass', 'Sex', 'Embarked'], drop_first=True)
| PassengerId | Survived | Name | Age | SibSp | Parch | Ticket | Fare | Cabin | Pclass_2 | Pclass_3 | Sex_male | Embarked_Q | Embarked_S | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 0 | Braund, Mr. Owen Harris | 22.0 | 1 | 0 | A/5 21171 | 7.2500 | NaN | 0 | 1 | 1 | 0 | 1 |
| 1 | 2 | 1 | Cumings, Mrs. John Bradley (Florence Briggs Th... | 38.0 | 1 | 0 | PC 17599 | 71.2833 | C85 | 0 | 0 | 0 | 0 | 0 |
| 2 | 3 | 1 | Heikkinen, Miss. Laina | 26.0 | 0 | 0 | STON/O2. 3101282 | 7.9250 | NaN | 0 | 1 | 0 | 0 | 1 |
| 3 | 4 | 1 | Futrelle, Mrs. Jacques Heath (Lily May Peel) | 35.0 | 1 | 0 | 113803 | 53.1000 | C123 | 0 | 0 | 0 | 0 | 1 |
| 4 | 5 | 0 | Allen, Mr. William Henry | 35.0 | 0 | 0 | 373450 | 8.0500 | NaN | 0 | 1 | 1 | 0 | 1 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 886 | 887 | 0 | Montvila, Rev. Juozas | 27.0 | 0 | 0 | 211536 | 13.0000 | NaN | 1 | 0 | 1 | 0 | 1 |
| 887 | 888 | 1 | Graham, Miss. Margaret Edith | 19.0 | 0 | 0 | 112053 | 30.0000 | B42 | 0 | 0 | 0 | 0 | 1 |
| 888 | 889 | 0 | Johnston, Miss. Catherine Helen "Carrie" | NaN | 1 | 2 | W./C. 6607 | 23.4500 | NaN | 0 | 1 | 0 | 0 | 1 |
| 889 | 890 | 1 | Behr, Mr. Karl Howell | 26.0 | 0 | 0 | 111369 | 30.0000 | C148 | 0 | 0 | 1 | 0 | 0 |
| 890 | 891 | 0 | Dooley, Mr. Patrick | 32.0 | 0 | 0 | 370376 | 7.7500 | NaN | 0 | 1 | 1 | 1 | 0 |
891 rows × 14 columns
group by
-
아래의 세 단계를 적용하여 데이터를 그룹화(groupping) (SQL의 group by 와 개념적으로는 동일, 사용법은 유사)
-
데이터 분할
-
operation 적용
-
데이터 병합
-
# data 출처: https://www.kaggle.com/hesh97/titanicdataset-traincsv/data
df = pd.read_csv('F:/data/titanic/train.csv')
df.head()
| PassengerId | Survived | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 0 | 3 | Braund, Mr. Owen Harris | male | 22.0 | 1 | 0 | A/5 21171 | 7.2500 | NaN | S |
| 1 | 2 | 1 | 1 | Cumings, Mrs. John Bradley (Florence Briggs Th... | female | 38.0 | 1 | 0 | PC 17599 | 71.2833 | C85 | C |
| 2 | 3 | 1 | 3 | Heikkinen, Miss. Laina | female | 26.0 | 0 | 0 | STON/O2. 3101282 | 7.9250 | NaN | S |
| 3 | 4 | 1 | 1 | Futrelle, Mrs. Jacques Heath (Lily May Peel) | female | 35.0 | 1 | 0 | 113803 | 53.1000 | C123 | S |
| 4 | 5 | 0 | 3 | Allen, Mr. William Henry | male | 35.0 | 0 | 0 | 373450 | 8.0500 | NaN | S |
GroupBy groups 속성
- 각 그룹과 그룹에 속한 index를 dict 형태로 표현
class_group = df.groupby('Pclass')
class_group # 이렇게 하면 groupby 객체가 만들어짐
<pandas.core.groupby.generic.DataFrameGroupBy object at 0x000002A260234DF0>
class_group.groups
{1: [1, 3, 6, 11, 23, 27, 30, 31, 34, 35, 52, 54, 55, 61, 62, 64, 83, 88, 92, 96, 97, 102, 110, 118, 124, 136, 137, 139, 151, 155, 166, 168, 170, 174, 177, 185, 187, 194, 195, 209, 215, 218, 224, 230, 245, 248, 252, 256, 257, 258, 262, 263, 268, 269, 270, 273, 275, 284, 290, 291, 295, 297, 298, 299, 305, 306, 307, 309, 310, 311, 318, 319, 325, 329, 331, 332, 334, 336, 337, 339, 341, 351, 356, 366, 369, 370, 373, 375, 377, 380, 383, 390, 393, 412, 430, 434, 435, 438, 445, 447, ...], 2: [9, 15, 17, 20, 21, 33, 41, 43, 53, 56, 58, 66, 70, 72, 78, 84, 98, 99, 117, 120, 122, 123, 133, 134, 135, 144, 145, 148, 149, 150, 161, 178, 181, 183, 190, 191, 193, 199, 211, 213, 217, 219, 221, 226, 228, 232, 234, 236, 237, 238, 239, 242, 247, 249, 259, 265, 272, 277, 288, 292, 303, 308, 312, 314, 316, 317, 322, 323, 327, 340, 342, 343, 344, 345, 346, 357, 361, 385, 387, 389, 397, 398, 399, 405, 407, 413, 416, 417, 418, 426, 427, 432, 437, 439, 440, 443, 446, 450, 458, 463, ...], 3: [0, 2, 4, 5, 7, 8, 10, 12, 13, 14, 16, 18, 19, 22, 24, 25, 26, 28, 29, 32, 36, 37, 38, 39, 40, 42, 44, 45, 46, 47, 48, 49, 50, 51, 57, 59, 60, 63, 65, 67, 68, 69, 71, 73, 74, 75, 76, 77, 79, 80, 81, 82, 85, 86, 87, 89, 90, 91, 93, 94, 95, 100, 101, 103, 104, 105, 106, 107, 108, 109, 111, 112, 113, 114, 115, 116, 119, 121, 125, 126, 127, 128, 129, 130, 131, 132, 138, 140, 141, 142, 143, 146, 147, 152, 153, 154, 156, 157, 158, 159, ...]}
gender_group = df.groupby('Sex')
gender_group.groups
{'female': [1, 2, 3, 8, 9, 10, 11, 14, 15, 18, 19, 22, 24, 25, 28, 31, 32, 38, 39, 40, 41, 43, 44, 47, 49, 52, 53, 56, 58, 61, 66, 68, 71, 79, 82, 84, 85, 88, 98, 100, 106, 109, 111, 113, 114, 119, 123, 128, 132, 133, 136, 140, 141, 142, 147, 151, 156, 161, 166, 167, 172, 177, 180, 184, 186, 190, 192, 194, 195, 198, 199, 205, 208, 211, 215, 216, 218, 229, 230, 233, 235, 237, 240, 241, 246, 247, 251, 254, 255, 256, 257, 258, 259, 264, 268, 269, 272, 274, 275, 276, ...], 'male': [0, 4, 5, 6, 7, 12, 13, 16, 17, 20, 21, 23, 26, 27, 29, 30, 33, 34, 35, 36, 37, 42, 45, 46, 48, 50, 51, 54, 55, 57, 59, 60, 62, 63, 64, 65, 67, 69, 70, 72, 73, 74, 75, 76, 77, 78, 80, 81, 83, 86, 87, 89, 90, 91, 92, 93, 94, 95, 96, 97, 99, 101, 102, 103, 104, 105, 107, 108, 110, 112, 115, 116, 117, 118, 120, 121, 122, 124, 125, 126, 127, 129, 130, 131, 134, 135, 137, 138, 139, 143, 144, 145, 146, 148, 149, 150, 152, 153, 154, 155, ...]}
groupping 함수
-
그룹 데이터에 적용 가능한 통계 함수(NaN은 제외하여 연산)
-
count - 데이터 개수
-
sum - 데이터의 합
-
mean, std, var - 평균, 표준편차, 분산
-
min, max - 최소, 최대값
class_group.count()
| PassengerId | Survived | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Pclass | |||||||||||
| 1 | 216 | 216 | 216 | 216 | 186 | 216 | 216 | 216 | 216 | 176 | 214 |
| 2 | 184 | 184 | 184 | 184 | 173 | 184 | 184 | 184 | 184 | 16 | 184 |
| 3 | 491 | 491 | 491 | 491 | 355 | 491 | 491 | 491 | 491 | 12 | 491 |
class_group.mean()['Age'] # 클래스별 나이 평균 계산
Pclass
1 38.233441
2 29.877630
3 25.140620
Name: Age, dtype: float64
class_group.mean()['Survived'] #클래스별 생존자 평균 계산
Pclass
1 0.629630
2 0.472826
3 0.242363
Name: Survived, dtype: float64
# class_group.max() #에러가 난다.
# class_group.min() #에러가 난다.
- 성별에 따른 생존율 구해보기
df.groupby('Sex').mean()['Survived']
Sex
female 0.742038
male 0.188908
Name: Survived, dtype: float64
복수 columns로 groupping 하기
-
groupby에 column 리스트를 전달
-
통계함수를 적용한 결과는 multiindex를 갖는 dataframe
-
클래스와 성별에 따른 생존률 구해보기
df.groupby(['Pclass', 'Sex']).mean()['Survived']
Pclass Sex
1 female 0.968085
male 0.368852
2 female 0.921053
male 0.157407
3 female 0.500000
male 0.135447
Name: Survived, dtype: float64
df.groupby(['Pclass', 'Sex']).mean().loc[(2, 'female')]
PassengerId 443.105263
Survived 0.921053
Age 28.722973
SibSp 0.486842
Parch 0.605263
Fare 21.970121
Name: (2, female), dtype: float64
df.groupby(['Pclass', 'Sex']).mean().index
MultiIndex([(1, 'female'),
(1, 'male'),
(2, 'female'),
(2, 'male'),
(3, 'female'),
(3, 'male')],
names=['Pclass', 'Sex'])
index를 이용한 group by
-
index가 있는 경우, groupby 함수에 level 사용 가능
- level은 index의 depth를 의미하며, 가장 왼쪽부터 0부터 증가
-
set_index 함수
-
column 데이터를 index 레벨로 변경
-
reset_index 함수
-
인덱스 초기화
df.head()
| PassengerId | Survived | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 0 | 3 | Braund, Mr. Owen Harris | male | 22.0 | 1 | 0 | A/5 21171 | 7.2500 | NaN | S |
| 1 | 2 | 1 | 1 | Cumings, Mrs. John Bradley (Florence Briggs Th... | female | 38.0 | 1 | 0 | PC 17599 | 71.2833 | C85 | C |
| 2 | 3 | 1 | 3 | Heikkinen, Miss. Laina | female | 26.0 | 0 | 0 | STON/O2. 3101282 | 7.9250 | NaN | S |
| 3 | 4 | 1 | 1 | Futrelle, Mrs. Jacques Heath (Lily May Peel) | female | 35.0 | 1 | 0 | 113803 | 53.1000 | C123 | S |
| 4 | 5 | 0 | 3 | Allen, Mr. William Henry | male | 35.0 | 0 | 0 | 373450 | 8.0500 | NaN | S |
df.set_index(['Pclass', 'Sex']).reset_index()
| Pclass | Sex | PassengerId | Survived | Name | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 3 | male | 1 | 0 | Braund, Mr. Owen Harris | 22.0 | 1 | 0 | A/5 21171 | 7.2500 | NaN | S |
| 1 | 1 | female | 2 | 1 | Cumings, Mrs. John Bradley (Florence Briggs Th... | 38.0 | 1 | 0 | PC 17599 | 71.2833 | C85 | C |
| 2 | 3 | female | 3 | 1 | Heikkinen, Miss. Laina | 26.0 | 0 | 0 | STON/O2. 3101282 | 7.9250 | NaN | S |
| 3 | 1 | female | 4 | 1 | Futrelle, Mrs. Jacques Heath (Lily May Peel) | 35.0 | 1 | 0 | 113803 | 53.1000 | C123 | S |
| 4 | 3 | male | 5 | 0 | Allen, Mr. William Henry | 35.0 | 0 | 0 | 373450 | 8.0500 | NaN | S |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 886 | 2 | male | 887 | 0 | Montvila, Rev. Juozas | 27.0 | 0 | 0 | 211536 | 13.0000 | NaN | S |
| 887 | 1 | female | 888 | 1 | Graham, Miss. Margaret Edith | 19.0 | 0 | 0 | 112053 | 30.0000 | B42 | S |
| 888 | 3 | female | 889 | 0 | Johnston, Miss. Catherine Helen "Carrie" | NaN | 1 | 2 | W./C. 6607 | 23.4500 | NaN | S |
| 889 | 1 | male | 890 | 1 | Behr, Mr. Karl Howell | 26.0 | 0 | 0 | 111369 | 30.0000 | C148 | C |
| 890 | 3 | male | 891 | 0 | Dooley, Mr. Patrick | 32.0 | 0 | 0 | 370376 | 7.7500 | NaN | Q |
891 rows × 12 columns
df.set_index('Age').groupby(level=0).mean() # level은 인덱스를 뜻함
| PassengerId | Survived | Pclass | SibSp | Parch | Fare | |
|---|---|---|---|---|---|---|
| Age | ||||||
| 0.42 | 804.0 | 1.0 | 3.0 | 0.0 | 1.0 | 8.5167 |
| 0.67 | 756.0 | 1.0 | 2.0 | 1.0 | 1.0 | 14.5000 |
| 0.75 | 557.5 | 1.0 | 3.0 | 2.0 | 1.0 | 19.2583 |
| 0.83 | 455.5 | 1.0 | 2.0 | 0.5 | 1.5 | 23.8750 |
| 0.92 | 306.0 | 1.0 | 1.0 | 1.0 | 2.0 | 151.5500 |
| ... | ... | ... | ... | ... | ... | ... |
| 70.00 | 709.5 | 0.0 | 1.5 | 0.5 | 0.5 | 40.7500 |
| 70.50 | 117.0 | 0.0 | 3.0 | 0.0 | 0.0 | 7.7500 |
| 71.00 | 295.5 | 0.0 | 1.0 | 0.0 | 0.0 | 42.0792 |
| 74.00 | 852.0 | 0.0 | 3.0 | 0.0 | 0.0 | 7.7750 |
| 80.00 | 631.0 | 1.0 | 1.0 | 0.0 | 0.0 | 30.0000 |
88 rows × 6 columns
나이대별로 생존율 구하기
def age_categorize(age): #연령별 카테고리화
if math.isnan(age):
return -1
return math.floor(age / 10) * 10
df.set_index('Age').groupby(age_categorize).mean()['Survived']
-1 0.293785
0 0.612903
10 0.401961
20 0.350000
30 0.437126
40 0.382022
50 0.416667
60 0.315789
70 0.000000
80 1.000000
Name: Survived, dtype: float64
MultiIndex를 이용한 groupping
df.set_index(['Pclass', 'Sex']).groupby(level=[0, 1]).mean()['Age'] # level은 인덱스를 뜻함
Pclass Sex
1 female 34.611765
male 41.281386
2 female 28.722973
male 30.740707
3 female 21.750000
male 26.507589
Name: Age, dtype: float64
aggregate(집계) 함수 사용하기
- groupby 결과에 집계함수를 적용하여 그룹별 데이터 확인 가능
df.set_index(['Pclass', 'Sex']).groupby(level=[0, 1]).aggregate([np.mean, np.sum, np.max])
| PassengerId | Survived | Age | SibSp | Parch | Fare | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| mean | sum | amax | mean | sum | amax | mean | sum | amax | mean | sum | amax | mean | sum | amax | mean | sum | amax | ||
| Pclass | Sex | ||||||||||||||||||
| 1 | female | 469.212766 | 44106 | 888 | 0.968085 | 91 | 1 | 34.611765 | 2942.00 | 63.0 | 0.553191 | 52 | 3 | 0.457447 | 43 | 2 | 106.125798 | 9975.8250 | 512.3292 |
| male | 455.729508 | 55599 | 890 | 0.368852 | 45 | 1 | 41.281386 | 4169.42 | 80.0 | 0.311475 | 38 | 3 | 0.278689 | 34 | 4 | 67.226127 | 8201.5875 | 512.3292 | |
| 2 | female | 443.105263 | 33676 | 881 | 0.921053 | 70 | 1 | 28.722973 | 2125.50 | 57.0 | 0.486842 | 37 | 3 | 0.605263 | 46 | 3 | 21.970121 | 1669.7292 | 65.0000 |
| male | 447.962963 | 48380 | 887 | 0.157407 | 17 | 1 | 30.740707 | 3043.33 | 70.0 | 0.342593 | 37 | 2 | 0.222222 | 24 | 2 | 19.741782 | 2132.1125 | 73.5000 | |
| 3 | female | 399.729167 | 57561 | 889 | 0.500000 | 72 | 1 | 21.750000 | 2218.50 | 63.0 | 0.895833 | 129 | 8 | 0.798611 | 115 | 6 | 16.118810 | 2321.1086 | 69.5500 |
| male | 455.515850 | 158064 | 891 | 0.135447 | 47 | 1 | 26.507589 | 6706.42 | 74.0 | 0.498559 | 173 | 8 | 0.224784 | 78 | 5 | 12.661633 | 4393.5865 | 69.5500 | |
transform 함수
-
groupby 후 transform 함수를 사용하면 원래의 index를 유지한 상태로 통계함수를 적용
-
전체 데이터의 집계가 아닌 각 그룹에서의 집계를 계산
-
따라서 새로 생성된 데이터를 원본 dataframe과 합치기 쉬움
df = pd.read_csv('E:\kaggle/titanic/train.csv')
df.groupby('Pclass').mean()
| PassengerId | Survived | Age | SibSp | Parch | Fare | |
|---|---|---|---|---|---|---|
| Pclass | ||||||
| 1 | 461.597222 | 0.629630 | 38.233441 | 0.416667 | 0.356481 | 84.154687 |
| 2 | 445.956522 | 0.472826 | 29.877630 | 0.402174 | 0.380435 | 20.662183 |
| 3 | 439.154786 | 0.242363 | 25.140620 | 0.615071 | 0.393075 | 13.675550 |
df.groupby('Pclass').transform(np.mean)
| PassengerId | Survived | Age | SibSp | Parch | Fare | |
|---|---|---|---|---|---|---|
| 0 | 439.154786 | 0.242363 | 25.140620 | 0.615071 | 0.393075 | 13.675550 |
| 1 | 461.597222 | 0.629630 | 38.233441 | 0.416667 | 0.356481 | 84.154687 |
| 2 | 439.154786 | 0.242363 | 25.140620 | 0.615071 | 0.393075 | 13.675550 |
| 3 | 461.597222 | 0.629630 | 38.233441 | 0.416667 | 0.356481 | 84.154687 |
| 4 | 439.154786 | 0.242363 | 25.140620 | 0.615071 | 0.393075 | 13.675550 |
| ... | ... | ... | ... | ... | ... | ... |
| 886 | 445.956522 | 0.472826 | 29.877630 | 0.402174 | 0.380435 | 20.662183 |
| 887 | 461.597222 | 0.629630 | 38.233441 | 0.416667 | 0.356481 | 84.154687 |
| 888 | 439.154786 | 0.242363 | 25.140620 | 0.615071 | 0.393075 | 13.675550 |
| 889 | 461.597222 | 0.629630 | 38.233441 | 0.416667 | 0.356481 | 84.154687 |
| 890 | 439.154786 | 0.242363 | 25.140620 | 0.615071 | 0.393075 | 13.675550 |
891 rows × 6 columns
df['Age2'] = df.groupby('Pclass').transform(np.mean)['Age']
df
| PassengerId | Survived | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked | Age2 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 0 | 3 | Braund, Mr. Owen Harris | male | 22.0 | 1 | 0 | A/5 21171 | 7.2500 | NaN | S | 25.140620 |
| 1 | 2 | 1 | 1 | Cumings, Mrs. John Bradley (Florence Briggs Th... | female | 38.0 | 1 | 0 | PC 17599 | 71.2833 | C85 | C | 38.233441 |
| 2 | 3 | 1 | 3 | Heikkinen, Miss. Laina | female | 26.0 | 0 | 0 | STON/O2. 3101282 | 7.9250 | NaN | S | 25.140620 |
| 3 | 4 | 1 | 1 | Futrelle, Mrs. Jacques Heath (Lily May Peel) | female | 35.0 | 1 | 0 | 113803 | 53.1000 | C123 | S | 38.233441 |
| 4 | 5 | 0 | 3 | Allen, Mr. William Henry | male | 35.0 | 0 | 0 | 373450 | 8.0500 | NaN | S | 25.140620 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 886 | 887 | 0 | 2 | Montvila, Rev. Juozas | male | 27.0 | 0 | 0 | 211536 | 13.0000 | NaN | S | 29.877630 |
| 887 | 888 | 1 | 1 | Graham, Miss. Margaret Edith | female | 19.0 | 0 | 0 | 112053 | 30.0000 | B42 | S | 38.233441 |
| 888 | 889 | 0 | 3 | Johnston, Miss. Catherine Helen "Carrie" | female | NaN | 1 | 2 | W./C. 6607 | 23.4500 | NaN | S | 25.140620 |
| 889 | 890 | 1 | 1 | Behr, Mr. Karl Howell | male | 26.0 | 0 | 0 | 111369 | 30.0000 | C148 | C | 38.233441 |
| 890 | 891 | 0 | 3 | Dooley, Mr. Patrick | male | 32.0 | 0 | 0 | 370376 | 7.7500 | NaN | Q | 25.140620 |
891 rows × 13 columns
df.groupby(['Pclass', 'Sex']).mean()
| PassengerId | Survived | Age | SibSp | Parch | Fare | Age2 | ||
|---|---|---|---|---|---|---|---|---|
| Pclass | Sex | |||||||
| 1 | female | 469.212766 | 0.968085 | 34.611765 | 0.553191 | 0.457447 | 106.125798 | 38.233441 |
| male | 455.729508 | 0.368852 | 41.281386 | 0.311475 | 0.278689 | 67.226127 | 38.233441 | |
| 2 | female | 443.105263 | 0.921053 | 28.722973 | 0.486842 | 0.605263 | 21.970121 | 29.877630 |
| male | 447.962963 | 0.157407 | 30.740707 | 0.342593 | 0.222222 | 19.741782 | 29.877630 | |
| 3 | female | 399.729167 | 0.500000 | 21.750000 | 0.895833 | 0.798611 | 16.118810 | 25.140620 |
| male | 455.515850 | 0.135447 | 26.507589 | 0.498559 | 0.224784 | 12.661633 | 25.140620 |
df['Age3'] = df.groupby(['Pclass', 'Sex']).transform(np.mean)['Age']
df
| PassengerId | Survived | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked | Age2 | Age3 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 0 | 3 | Braund, Mr. Owen Harris | male | 22.0 | 1 | 0 | A/5 21171 | 7.2500 | NaN | S | 25.140620 | 26.507589 |
| 1 | 2 | 1 | 1 | Cumings, Mrs. John Bradley (Florence Briggs Th... | female | 38.0 | 1 | 0 | PC 17599 | 71.2833 | C85 | C | 38.233441 | 34.611765 |
| 2 | 3 | 1 | 3 | Heikkinen, Miss. Laina | female | 26.0 | 0 | 0 | STON/O2. 3101282 | 7.9250 | NaN | S | 25.140620 | 21.750000 |
| 3 | 4 | 1 | 1 | Futrelle, Mrs. Jacques Heath (Lily May Peel) | female | 35.0 | 1 | 0 | 113803 | 53.1000 | C123 | S | 38.233441 | 34.611765 |
| 4 | 5 | 0 | 3 | Allen, Mr. William Henry | male | 35.0 | 0 | 0 | 373450 | 8.0500 | NaN | S | 25.140620 | 26.507589 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 886 | 887 | 0 | 2 | Montvila, Rev. Juozas | male | 27.0 | 0 | 0 | 211536 | 13.0000 | NaN | S | 29.877630 | 30.740707 |
| 887 | 888 | 1 | 1 | Graham, Miss. Margaret Edith | female | 19.0 | 0 | 0 | 112053 | 30.0000 | B42 | S | 38.233441 | 34.611765 |
| 888 | 889 | 0 | 3 | Johnston, Miss. Catherine Helen "Carrie" | female | NaN | 1 | 2 | W./C. 6607 | 23.4500 | NaN | S | 25.140620 | 21.750000 |
| 889 | 890 | 1 | 1 | Behr, Mr. Karl Howell | male | 26.0 | 0 | 0 | 111369 | 30.0000 | C148 | C | 38.233441 | 41.281386 |
| 890 | 891 | 0 | 3 | Dooley, Mr. Patrick | male | 32.0 | 0 | 0 | 370376 | 7.7500 | NaN | Q | 25.140620 | 26.507589 |
891 rows × 14 columns
- pivot, pivot_table 함수의 이해
df = pd.DataFrame({
'지역': ['서울', '서울', '서울', '경기', '경기', '부산', '서울', '서울', '부산', '경기', '경기', '경기'],
'요일': ['월요일', '화요일', '수요일', '월요일', '화요일', '월요일', '목요일', '금요일', '화요일', '수요일', '목요일', '금요일'],
'강수량': [100, 80, 1000, 200, 200, 100, 50, 100, 200, 100, 50, 100],
'강수확률': [80, 70, 90, 10, 20, 30, 50, 90, 20, 80, 50, 10]
})
df
| 지역 | 요일 | 강수량 | 강수확률 | |
|---|---|---|---|---|
| 0 | 서울 | 월요일 | 100 | 80 |
| 1 | 서울 | 화요일 | 80 | 70 |
| 2 | 서울 | 수요일 | 1000 | 90 |
| 3 | 경기 | 월요일 | 200 | 10 |
| 4 | 경기 | 화요일 | 200 | 20 |
| 5 | 부산 | 월요일 | 100 | 30 |
| 6 | 서울 | 목요일 | 50 | 50 |
| 7 | 서울 | 금요일 | 100 | 90 |
| 8 | 부산 | 화요일 | 200 | 20 |
| 9 | 경기 | 수요일 | 100 | 80 |
| 10 | 경기 | 목요일 | 50 | 50 |
| 11 | 경기 | 금요일 | 100 | 10 |
pivot
-
dataframe의 형태를 변경
-
인덱스, 컬럼, 데이터로 사용할 컬럼을 명시
# 피벗은 보기 좋게
df.pivot('지역', '요일') # 지역이 index, 요일이 columns
#에러
| 강수량 | 강수확률 | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| 요일 | 금요일 | 목요일 | 수요일 | 월요일 | 화요일 | 금요일 | 목요일 | 수요일 | 월요일 | 화요일 |
| 지역 | ||||||||||
| 경기 | 100.0 | 50.0 | 100.0 | 200.0 | 200.0 | 10.0 | 50.0 | 80.0 | 10.0 | 20.0 |
| 부산 | NaN | NaN | NaN | 100.0 | 200.0 | NaN | NaN | NaN | 30.0 | 20.0 |
| 서울 | 100.0 | 50.0 | 1000.0 | 100.0 | 80.0 | 90.0 | 50.0 | 90.0 | 80.0 | 70.0 |
df.pivot('요일', '지역')
| 강수량 | 강수확률 | |||||
|---|---|---|---|---|---|---|
| 지역 | 경기 | 부산 | 서울 | 경기 | 부산 | 서울 |
| 요일 | ||||||
| 금요일 | 100.0 | NaN | 100.0 | 10.0 | NaN | 90.0 |
| 목요일 | 50.0 | NaN | 50.0 | 50.0 | NaN | 50.0 |
| 수요일 | 100.0 | NaN | 1000.0 | 80.0 | NaN | 90.0 |
| 월요일 | 200.0 | 100.0 | 100.0 | 10.0 | 30.0 | 80.0 |
| 화요일 | 200.0 | 200.0 | 80.0 | 20.0 | 20.0 | 70.0 |
pivot_table
-
기능적으로 pivot과 동일
-
pivot과의 차이점
- 중복되는 모호한 값이 있을 경우, aggregation 함수 사용하여 값을 채움
pd.pivot_table(df,index='요일', columns='지역', aggfunc=np.mean)
| 강수량 | 강수확률 | |||||
|---|---|---|---|---|---|---|
| 지역 | 경기 | 부산 | 서울 | 경기 | 부산 | 서울 |
| 요일 | ||||||
| 금요일 | 100.0 | NaN | 100.0 | 10.0 | NaN | 90.0 |
| 목요일 | 50.0 | NaN | 50.0 | 50.0 | NaN | 50.0 |
| 수요일 | 100.0 | NaN | 1000.0 | 80.0 | NaN | 90.0 |
| 월요일 | 200.0 | 100.0 | 100.0 | 10.0 | 30.0 | 80.0 |
| 화요일 | 200.0 | 200.0 | 80.0 | 20.0 | 20.0 | 70.0 |
stack & unstack
-
stack : 컬럼 레벨에서 인덱스 레벨로 dataframe 변경
-
즉, 데이터를 쌓아올리는 개념으로 이해하면 쉬움
-
unstack : 인덱스 레벨에서 컬럼 레벨로 dataframe 변경
-
stack의 반대 operation
-
둘은 역의 관계에 있음
new_df = df.set_index(['지역', '요일'])
new_df
| 강수량 | 강수확률 | ||
|---|---|---|---|
| 지역 | 요일 | ||
| 서울 | 월요일 | 100 | 80 |
| 화요일 | 80 | 70 | |
| 수요일 | 1000 | 90 | |
| 경기 | 월요일 | 200 | 10 |
| 화요일 | 200 | 20 | |
| 부산 | 월요일 | 100 | 30 |
| 서울 | 목요일 | 50 | 50 |
| 금요일 | 100 | 90 | |
| 부산 | 화요일 | 200 | 20 |
| 경기 | 수요일 | 100 | 80 |
| 목요일 | 50 | 50 | |
| 금요일 | 100 | 10 |
new_df.unstack(0) # 0이면 지역 인덱스를 컬럼레벨로 올려라
| 강수량 | 강수확률 | |||||
|---|---|---|---|---|---|---|
| 지역 | 경기 | 부산 | 서울 | 경기 | 부산 | 서울 |
| 요일 | ||||||
| 금요일 | 100.0 | NaN | 100.0 | 10.0 | NaN | 90.0 |
| 목요일 | 50.0 | NaN | 50.0 | 50.0 | NaN | 50.0 |
| 수요일 | 100.0 | NaN | 1000.0 | 80.0 | NaN | 90.0 |
| 월요일 | 200.0 | 100.0 | 100.0 | 10.0 | 30.0 | 80.0 |
| 화요일 | 200.0 | 200.0 | 80.0 | 20.0 | 20.0 | 70.0 |
new_df.unstack(1) # 1이면 요일 인덱스를 컬럼레벨로 올려라
| 강수량 | 강수확률 | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| 요일 | 금요일 | 목요일 | 수요일 | 월요일 | 화요일 | 금요일 | 목요일 | 수요일 | 월요일 | 화요일 |
| 지역 | ||||||||||
| 경기 | 100.0 | 50.0 | 100.0 | 200.0 | 200.0 | 10.0 | 50.0 | 80.0 | 10.0 | 20.0 |
| 부산 | NaN | NaN | NaN | 100.0 | 200.0 | NaN | NaN | NaN | 30.0 | 20.0 |
| 서울 | 100.0 | 50.0 | 1000.0 | 100.0 | 80.0 | 90.0 | 50.0 | 90.0 | 80.0 | 70.0 |
new_df.unstack(0).stack(0)
| 지역 | 경기 | 부산 | 서울 | |
|---|---|---|---|---|
| 요일 | ||||
| 금요일 | 강수량 | 100.0 | NaN | 100.0 |
| 강수확률 | 10.0 | NaN | 90.0 | |
| 목요일 | 강수량 | 50.0 | NaN | 50.0 |
| 강수확률 | 50.0 | NaN | 50.0 | |
| 수요일 | 강수량 | 100.0 | NaN | 1000.0 |
| 강수확률 | 80.0 | NaN | 90.0 | |
| 월요일 | 강수량 | 200.0 | 100.0 | 100.0 |
| 강수확률 | 10.0 | 30.0 | 80.0 | |
| 화요일 | 강수량 | 200.0 | 200.0 | 80.0 |
| 강수확률 | 20.0 | 20.0 | 70.0 |
new_df.unstack(0).stack(1) #-1은 마지막
| 강수량 | 강수확률 | ||
|---|---|---|---|
| 요일 | 지역 | ||
| 금요일 | 경기 | 100.0 | 10.0 |
| 서울 | 100.0 | 90.0 | |
| 목요일 | 경기 | 50.0 | 50.0 |
| 서울 | 50.0 | 50.0 | |
| 수요일 | 경기 | 100.0 | 80.0 |
| 서울 | 1000.0 | 90.0 | |
| 월요일 | 경기 | 200.0 | 10.0 |
| 부산 | 100.0 | 30.0 | |
| 서울 | 100.0 | 80.0 | |
| 화요일 | 경기 | 200.0 | 20.0 |
| 부산 | 200.0 | 20.0 | |
| 서울 | 80.0 | 70.0 |
concat 함수 사용하여 dataframe 병합하기
-
pandas.concat 함수
-
축을 따라 dataframe을 병합 가능
- 기본 axis = 0 -> 행단위 병합
-
column명이 같은 경우
# concat은 단순하게 합침
df1 = pd.DataFrame({'key1' : np.arange(10), 'value1' : np.random.randn(10)})
df2 = pd.DataFrame({'key1' : np.arange(10), 'value1' : np.random.randn(10)})
pd.concat([df1, df2], ignore_index=True) # index는 유지. 하지만 ignore_index쓰면 바뀜
| key1 | value1 | |
|---|---|---|
| 0 | 0 | -0.112312 |
| 1 | 1 | 0.611798 |
| 2 | 2 | 0.189342 |
| 3 | 3 | -1.027669 |
| 4 | 4 | -1.069512 |
| 5 | 5 | -1.680114 |
| 6 | 6 | -1.338902 |
| 7 | 7 | 0.449318 |
| 8 | 8 | 0.273951 |
| 9 | 9 | 1.077814 |
| 10 | 0 | 0.281915 |
| 11 | 1 | 0.320075 |
| 12 | 2 | -0.296429 |
| 13 | 3 | -1.420309 |
| 14 | 4 | -0.847101 |
| 15 | 5 | -0.518147 |
| 16 | 6 | -0.082555 |
| 17 | 7 | -0.254324 |
| 18 | 8 | -0.977181 |
| 19 | 9 | 0.265628 |
pd.concat([df1, df2], axis=1)
| key1 | value1 | key1 | value1 | |
|---|---|---|---|---|
| 0 | 0 | -0.112312 | 0 | 0.281915 |
| 1 | 1 | 0.611798 | 1 | 0.320075 |
| 2 | 2 | 0.189342 | 2 | -0.296429 |
| 3 | 3 | -1.027669 | 3 | -1.420309 |
| 4 | 4 | -1.069512 | 4 | -0.847101 |
| 5 | 5 | -1.680114 | 5 | -0.518147 |
| 6 | 6 | -1.338902 | 6 | -0.082555 |
| 7 | 7 | 0.449318 | 7 | -0.254324 |
| 8 | 8 | 0.273951 | 8 | -0.977181 |
| 9 | 9 | 1.077814 | 9 | 0.265628 |
column 명이 다른 경우
df3 = pd.DataFrame({'key2' : np.arange(10), 'value2' : np.random.randn(10)})
pd.concat([df1, df3], axis=1)
| key1 | value1 | key2 | value2 | |
|---|---|---|---|---|
| 0 | 0 | -0.112312 | 0 | -1.300134 |
| 1 | 1 | 0.611798 | 1 | 0.530596 |
| 2 | 2 | 0.189342 | 2 | 0.032435 |
| 3 | 3 | -1.027669 | 3 | 0.269433 |
| 4 | 4 | -1.069512 | 4 | -0.216506 |
| 5 | 5 | -1.680114 | 5 | 0.110930 |
| 6 | 6 | -1.338902 | 6 | -0.371537 |
| 7 | 7 | 0.449318 | 7 | 0.522430 |
| 8 | 8 | 0.273951 | 8 | -2.454415 |
| 9 | 9 | 1.077814 | 9 | -0.803864 |
dataframe merge
-
SQL의 join처럼 특정한 column을 기준으로 병합
-
join 방식: how 파라미터를 통해 명시
-
inner: 기본값, 일치하는 값이 있는 경우
-
left: left outer join
-
right: right outer join
-
outer: full outer join
-
-
-
pandas.merge 함수가 사용됨
customer = pd.DataFrame({'customer_id' : np.arange(6),
'name' : ['철수'"", '영희', '길동', '영수', '수민', '동건'],
'나이' : [40, 20, 21, 30, 31, 18]})
customer
| customer_id | name | 나이 | |
|---|---|---|---|
| 0 | 0 | 철수 | 40 |
| 1 | 1 | 영희 | 20 |
| 2 | 2 | 길동 | 21 |
| 3 | 3 | 영수 | 30 |
| 4 | 4 | 수민 | 31 |
| 5 | 5 | 동건 | 18 |
orders = pd.DataFrame({'customer_id' : [1, 1, 2, 2, 2, 3, 3, 1, 4, 9],
'item' : ['치약', '칫솔', '이어폰', '헤드셋', '수건', '생수', '수건', '치약', '생수', '케이스'],
'quantity' : [1, 2, 1, 1, 3, 2, 2, 3, 2, 1]})
orders.head()
| customer_id | item | quantity | |
|---|---|---|---|
| 0 | 1 | 치약 | 1 |
| 1 | 1 | 칫솔 | 2 |
| 2 | 2 | 이어폰 | 1 |
| 3 | 2 | 헤드셋 | 1 |
| 4 | 2 | 수건 | 3 |
on
- join 대상이 되는 column 명시
pd.merge(customer, orders, on='customer_id', how='inner') # customer_id를 기준으로
# 일치하는 것만 가져옴
# on은 머지를 하게 될 대상, 컬럼을 명시
# how은 어떤 식으로 머지를 할 것인지
| customer_id | name | 나이 | item | quantity | |
|---|---|---|---|---|---|
| 0 | 1 | 영희 | 20 | 치약 | 1 |
| 1 | 1 | 영희 | 20 | 칫솔 | 2 |
| 2 | 1 | 영희 | 20 | 치약 | 3 |
| 3 | 2 | 길동 | 21 | 이어폰 | 1 |
| 4 | 2 | 길동 | 21 | 헤드셋 | 1 |
| 5 | 2 | 길동 | 21 | 수건 | 3 |
| 6 | 3 | 영수 | 30 | 생수 | 2 |
| 7 | 3 | 영수 | 30 | 수건 | 2 |
| 8 | 4 | 수민 | 31 | 생수 | 2 |
pd.merge(customer, orders, on='customer_id', how='left')
| customer_id | name | 나이 | item | quantity | |
|---|---|---|---|---|---|
| 0 | 0 | 철수 | 40 | NaN | NaN |
| 1 | 1 | 영희 | 20 | 치약 | 1.0 |
| 2 | 1 | 영희 | 20 | 칫솔 | 2.0 |
| 3 | 1 | 영희 | 20 | 치약 | 3.0 |
| 4 | 2 | 길동 | 21 | 이어폰 | 1.0 |
| 5 | 2 | 길동 | 21 | 헤드셋 | 1.0 |
| 6 | 2 | 길동 | 21 | 수건 | 3.0 |
| 7 | 3 | 영수 | 30 | 생수 | 2.0 |
| 8 | 3 | 영수 | 30 | 수건 | 2.0 |
| 9 | 4 | 수민 | 31 | 생수 | 2.0 |
| 10 | 5 | 동건 | 18 | NaN | NaN |
pd.merge(customer, orders, on='customer_id', how='right')
| customer_id | name | 나이 | item | quantity | |
|---|---|---|---|---|---|
| 0 | 1 | 영희 | 20.0 | 치약 | 1 |
| 1 | 1 | 영희 | 20.0 | 칫솔 | 2 |
| 2 | 1 | 영희 | 20.0 | 치약 | 3 |
| 3 | 2 | 길동 | 21.0 | 이어폰 | 1 |
| 4 | 2 | 길동 | 21.0 | 헤드셋 | 1 |
| 5 | 2 | 길동 | 21.0 | 수건 | 3 |
| 6 | 3 | 영수 | 30.0 | 생수 | 2 |
| 7 | 3 | 영수 | 30.0 | 수건 | 2 |
| 8 | 4 | 수민 | 31.0 | 생수 | 2 |
| 9 | 9 | NaN | NaN | 케이스 | 1 |
pd.merge(customer, orders, on='customer_id', how='outer')
# outer는 left와 right을 합친 것
| customer_id | name | 나이 | item | quantity | |
|---|---|---|---|---|---|
| 0 | 0 | 철수 | 40.0 | NaN | NaN |
| 1 | 1 | 영희 | 20.0 | 치약 | 1.0 |
| 2 | 1 | 영희 | 20.0 | 칫솔 | 2.0 |
| 3 | 1 | 영희 | 20.0 | 치약 | 3.0 |
| 4 | 2 | 길동 | 21.0 | 이어폰 | 1.0 |
| 5 | 2 | 길동 | 21.0 | 헤드셋 | 1.0 |
| 6 | 2 | 길동 | 21.0 | 수건 | 3.0 |
| 7 | 3 | 영수 | 30.0 | 생수 | 2.0 |
| 8 | 3 | 영수 | 30.0 | 수건 | 2.0 |
| 9 | 4 | 수민 | 31.0 | 생수 | 2.0 |
| 10 | 5 | 동건 | 18.0 | NaN | NaN |
| 11 | 9 | NaN | NaN | 케이스 | 1.0 |
cust1 = customer.set_index('customer_id')
order1 = orders.set_index('customer_id')
cust1
| name | 나이 | |
|---|---|---|
| customer_id | ||
| 0 | 철수 | 40 |
| 1 | 영희 | 20 |
| 2 | 길동 | 21 |
| 3 | 영수 | 30 |
| 4 | 수민 | 31 |
| 5 | 동건 | 18 |
order1
| item | quantity | |
|---|---|---|
| customer_id | ||
| 1 | 치약 | 1 |
| 1 | 칫솔 | 2 |
| 2 | 이어폰 | 1 |
| 2 | 헤드셋 | 1 |
| 2 | 수건 | 3 |
| 3 | 생수 | 2 |
| 3 | 수건 | 2 |
| 1 | 치약 | 3 |
| 4 | 생수 | 2 |
| 9 | 케이스 | 1 |
pd.merge(cust1, order1, left_index=True, right_index=True)
# on을 설정할 필요가 없음
| name | 나이 | item | quantity | |
|---|---|---|---|---|
| customer_id | ||||
| 1 | 영희 | 20 | 치약 | 1 |
| 1 | 영희 | 20 | 칫솔 | 2 |
| 1 | 영희 | 20 | 치약 | 3 |
| 2 | 길동 | 21 | 이어폰 | 1 |
| 2 | 길동 | 21 | 헤드셋 | 1 |
| 2 | 길동 | 21 | 수건 | 3 |
| 3 | 영수 | 30 | 생수 | 2 |
| 3 | 영수 | 30 | 수건 | 2 |
| 4 | 수민 | 31 | 생수 | 2 |
# 가장 많이 팔린 아이템은?
pd.merge(customer, orders, on='customer_id').groupby('item').sum().sort_values(by='quantity', ascending=False)
# 수건이 가장 많이 팔림
| customer_id | 나이 | quantity | |
|---|---|---|---|
| item | |||
| 수건 | 5 | 51 | 5 |
| 생수 | 7 | 61 | 4 |
| 치약 | 2 | 40 | 4 |
| 칫솔 | 1 | 20 | 2 |
| 이어폰 | 2 | 21 | 1 |
| 헤드셋 | 2 | 21 | 1 |
#영희가 가장 많이 구매한 아이템은?
pd.merge(customer, orders, on='customer_id').groupby(['name', 'item']).sum().loc['영희', 'quantity']
item
치약 4
칫솔 2
Name: quantity, dtype: int64
join 함수
-
내부적으로 pandas.merge 함수 사용
-
기본적으로 index를 사용하여 left join
cust1.join(order1, how='inner')
| name | 나이 | item | quantity | |
|---|---|---|---|---|
| customer_id | ||||
| 1 | 영희 | 20 | 치약 | 1 |
| 1 | 영희 | 20 | 칫솔 | 2 |
| 1 | 영희 | 20 | 치약 | 3 |
| 2 | 길동 | 21 | 이어폰 | 1 |
| 2 | 길동 | 21 | 헤드셋 | 1 |
| 2 | 길동 | 21 | 수건 | 3 |
| 3 | 영수 | 30 | 생수 | 2 |
| 3 | 영수 | 30 | 수건 | 2 |
| 4 | 수민 | 31 | 생수 | 2 |
댓글남기기