파이썬 pandas 라이브러리에 대한 모든 것
라이브러리 불러오기
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 |
댓글남기기