Python

Pandas 기초

2020. 7. 16. 17:25

가장 많이 사용하는 것들 위주로 정리

Pandas 시작 - 파일을 DataFrame 로딩, 기본 API

  • 웨스 매키니(Wes McKinney) 월스트리트 금융회사 분석 전문가

  • 회사에서 사용하는 분석용 데이터 핸들링 툴이 마음에 안들어서 Pandas 개발

  • 행과 열로 이루어진 2차원 데이터를 효율적으로 가공/처리할 수 있는 기능 제공

  • 파이썬의 리스트, 넘파이, CSV등 파일을 쉽게 DataFrame으로 변경해 데이터의 가공/분석을 편리하게 수행

Series

  • 칼럼이 하나 뿐인 데이터 구조체

DataFrame

  • 컬럼이 여러 개인 데이터 구조체

  • 여러개의 Series로 구성

Index

  • RDBMS의 PK 처럼 개별 데이터를 고유하게 식별하는 Key 값

  • Series, DataFrame은 모두 index를 Key 값으로 가짐

Install Pandas

#pip install pandas
import pandas as pd

Dataset download

# tab으로 구분된 파일은 read.table() 사용
# 첫 줄 header = T가 default
titanic_df = pd.read_csv('titanic_train.csv')
print('titanic 변수 type :',type(titanic_df))
titanic_df.head(3)
titanic 변수 type : <class 'pandas.core.frame.DataFrame'>
  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
titanic_df.shape
(891, 12)
# 상세 정보조회 : 컬럼타입, Null Data 개수 등
# object : 거의 문자열, Age, Cabin 컬럼에 Null 값이 많이 있음
# R의 str()과 동일
titanic_df.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
# R의 summary() 같은 함수
# 숫자형의 분포를 보여줌, object 타입의 칼럼은 제외
# 데이터의 분포도는 중요 : 회귀분석에서 결정 값이 정규분포를 따르지 않는 다던가 이상치가 많으면 예측치가 저하됨
# 카테고리 칼럼(Survived 0,1 : Pclass 1,2,3)도 확인 가능(R의 Facter형)
# 중앙값은 50%의 값으로 확인
titanic_df.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
# DataFrame[컬럼명] : Series 형태로 특정 칼럼 데이터 세트를 반환
# value_counts() : Sereis의 유형별 건수 확인, R의 table()
value_counts = titanic_df['Pclass'].value_counts()
print(value_counts)
3    491
1    216
2    184
Name: Pclass, dtype: int64
# type 확인
titanic_pclass = titanic_df['Pclass']
print(type(titanic_pclass))
<class 'pandas.core.series.Series'>
# Series - Index(좌) : value(우)
titanic_pclass.head()
0    3
1    1
2    3
3    1
4    3
Name: Pclass, dtype: int64
value_counts = titanic_df['Pclass'].value_counts()
print(type(value_counts))
print(value_counts) # 3 1 2 가 index
<class 'pandas.core.series.Series'>
3    491
1    216
2    184
Name: Pclass, dtype: int64
value_counts.index
Int64Index([3, 1, 2], dtype='int64')

DataFrame과 리스트, 딕셔너리, 넘파이 ndarray 상호 변환

  • 넘파이 ndarray, 리스트, 딕셔너리를 DataFrame으로 변환하기

# 사이킷런의 많은 API는 DataFrame 인자 사용, 기본은 ndarray 사용, pd 와 nd 상호 간 변환이 매우 빈번하게 발생
# Pandas는 컬럼명을 가지고 있어 다루기 더 편함
# 칼럼명을 지정하지 않으면 자동으로 칼럼명 할당
# columns 속성에 list 값으로 생성 가능
import numpy as np

# 1차원 컬럼 1개 필요
col_name1 = ['col1']
list1 = [1, 2, 3]
array1 = np.array(list1)

print('array1 shape :', array1.shape)
df_list1 = pd.DataFrame(list1, columns = col_name1)
print('1차원 리스트로 만든 DataFrame :\n', df_list1)
df_array1 = pd.DataFrame(array1, columns=col_name1)
print('1차원 ndarray로 만든 DataFrame :\n', df_array1)
array1 shape : (3,)
1차원 리스트로 만든 DataFrame :
    col1
0     1
1     2
2     3
1차원 ndarray로 만든 DataFrame :
    col1
0     1
1     2
2     3
# 2차원 2 x 3 3개의 컬럼명이 필요함. 
col_name2=['col1', 'col2', 'col3']

# 2행x3열 형태의 리스트와 ndarray 생성 한 뒤 이를 DataFrame으로 변환. 
list2 = [[1, 2, 3],
         [11, 12, 13]]
array2 = np.array(list2)
print('array2 shape:', array2.shape )
df_list2 = pd.DataFrame(list2, columns=col_name2)
print('2차원 리스트로 만든 DataFrame:\n', df_list2)
df_array2 = pd.DataFrame(array2, columns=col_name2)
print('2차원 ndarray로 만든 DataFrame:\n', df_array2)
array2 shape: (2, 3)
2차원 리스트로 만든 DataFrame:
    col1  col2  col3
0     1     2     3
1    11    12    13
2차원 ndarray로 만든 DataFrame:
    col1  col2  col3
0     1     2     3
1    11    12    13
# dict 형은 Key는 컬럼명으로 매핑, Value는 리스트 형(또는 ndarray)
dict_1 = {'col1':[1, 11], 'col2':[2, 22], 'col3':[3, 33]}
df_dict = pd.DataFrame(dict_1)
print('딕셔너리로 만든 DataFrame:\n', df_dict)
딕셔너리로 만든 DataFrame:
    col1  col2  col3
0     1     2     3
1    11    22    33

values 속성

  • DataFrame을 넘파이 ndarray, 리스트, 딕셔너리로 변환하기

# values 속성은 DataFrame을 ndarray로 변환 (pd -> ndarray)
array3 = df_dict.values
print('df_dict.values 타입:', type(array3), 'df_dict.values shape:', array3.shape)
print(array3)
df_dict.values 타입: <class 'numpy.ndarray'> df_dict.values shape: (2, 3)
[[ 1  2  3]
 [11 22 33]]
# DataFrame을 리스트로 변환
list3 = df_dict.values.tolist()
print('df_dict.values.tolist() 타입:', type(list3))
print(list3)

# DataFrame을 딕셔너리로 변환
dict3 = df_dict.to_dict('list')
print('\n df_dict.to_dict() 타입:', type(dict3))
print(dict3)
df_dict.values.tolist() 타입: <class 'list'>
[[1, 2, 3], [11, 22, 33]]

 df_dict.to_dict() 타입: <class 'dict'>
{'col1': [1, 11], 'col2': [2, 22], 'col3': [3, 33]}

DataFrame의 컬럼 데이터 셋 Access

# 새로운 칼럼(Series) 추가, 초기화
titanic_df['Age_0']=0
titanic_df.head(3)
  PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked Age_0
0 1 0 3 Braund, Mr. Owen Harris male 22.0 1 0 A/5 21171 7.2500 NaN S 0
1 2 1 1 Cumings, Mrs. John Bradley (Florence Briggs Th... female 38.0 1 0 PC 17599 71.2833 C85 C 0
2 3 1 3 Heikkinen, Miss. Laina female 26.0 0 0 STON/O2. 3101282 7.9250 NaN S 0
# 기존 컬럼이용하여 새로운 컬럼 생성
titanic_df['Age_by_10'] = titanic_df['Age']*10
titanic_df['Family_No'] = titanic_df['SibSp'] + titanic_df['Parch']+1
titanic_df.head(3)
  PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked Age_0 Age_by_10 Family_No
0 1 0 3 Braund, Mr. Owen Harris male 22.0 1 0 A/5 21171 7.2500 NaN S 0 220.0 2
1 2 1 1 Cumings, Mrs. John Bradley (Florence Briggs Th... female 38.0 1 0 PC 17599 71.2833 C85 C 0 380.0 2
2 3 1 3 Heikkinen, Miss. Laina female 26.0 0 0 STON/O2. 3101282 7.9250 NaN S 0 260.0 1
titanic_df['Age_by_10'] = titanic_df['Age_by_10'] + 100
titanic_df.head(3)
  PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked Age_0 Age_by_10 Family_No
0 1 0 3 Braund, Mr. Owen Harris male 22.0 1 0 A/5 21171 7.2500 NaN S 0 320.0 2
1 2 1 1 Cumings, Mrs. John Bradley (Florence Briggs Th... female 38.0 1 0 PC 17599 71.2833 C85 C 0 480.0 2
2 3 1 3 Heikkinen, Miss. Laina female 26.0 0 0 STON/O2. 3101282 7.9250 NaN S 0 360.0 1

DataFrame 데이터 삭제

  • drop() 사용

  • axis 0 : 로우 방향 축, 1: 컬럼 방향 축

titanic_drop_df = titanic_df.drop('Age_0', axis=1 ) # 컬럼 삭제
titanic_drop_df.head(3)
  PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked Age_by_10 Family_No
0 1 0 3 Braund, Mr. Owen Harris male 22.0 1 0 A/5 21171 7.2500 NaN S 320.0 2
1 2 1 1 Cumings, Mrs. John Bradley (Florence Briggs Th... female 38.0 1 0 PC 17599 71.2833 C85 C 480.0 2
2 3 1 3 Heikkinen, Miss. Laina female 26.0 0 0 STON/O2. 3101282 7.9250 NaN S 360.0 1
# 원본데이터는 삭제 되지 않았음 inplace=False 
titanic_df.head(3)
  PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked Age_0 Age_by_10 Family_No
0 1 0 3 Braund, Mr. Owen Harris male 22.0 1 0 A/5 21171 7.2500 NaN S 0 320.0 2
1 2 1 1 Cumings, Mrs. John Bradley (Florence Briggs Th... female 38.0 1 0 PC 17599 71.2833 C85 C 0 480.0 2
2 3 1 3 Heikkinen, Miss. Laina female 26.0 0 0 STON/O2. 3101282 7.9250 NaN S 0 360.0 1
# 원본 데이터도 삭제 inplace=True
# 여러개 삭제 시 리스트 값
drop_result = titanic_df.drop(['Age_0', 'Age_by_10', 'Family_No'], axis=1, inplace=True)
print(' inplace=True 로 drop 후 반환된 값 :',drop_result) # 반환값 None
titanic_df.head(3)
 inplace=True 로 drop 후 반환된 값 : None
  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
#pd.set_option('display.width', 1000)
#pd.set_option('display.max_colwidth', 15)
print('#### before axis 0 drop ####')
print(titanic_df.head(3))

titanic_df.drop([0,1,2], axis=0, inplace=True)

print('#### after axis 0 drop ####')
print(titanic_df.head(3))
#### before axis 0 drop ####
   PassengerId  Survived  Pclass  \
0            1         0       3   
1            2         1       1   
2            3         1       3   

                                                Name     Sex   Age  SibSp  \
0                            Braund, Mr. Owen Harris    male  22.0      1   
1  Cumings, Mrs. John Bradley (Florence Briggs Th...  female  38.0      1   
2                             Heikkinen, Miss. Laina  female  26.0      0   

   Parch            Ticket     Fare Cabin Embarked  
0      0         A/5 21171   7.2500   NaN        S  
1      0          PC 17599  71.2833   C85        C  
2      0  STON/O2. 3101282   7.9250   NaN        S  
#### after axis 0 drop ####
   PassengerId  Survived  Pclass  \
3            4         1       1   
4            5         0       3   
5            6         0       3   

                                           Name     Sex   Age  SibSp  Parch  \
3  Futrelle, Mrs. Jacques Heath (Lily May Peel)  female  35.0      1      0   
4                      Allen, Mr. William Henry    male  35.0      0      0   
5                              Moran, Mr. James    male   NaN      0      0   

   Ticket     Fare Cabin Embarked  
3  113803  53.1000  C123        S  
4  373450   8.0500   NaN        S  
5  330877   8.4583   NaN        Q  

Index 객체

  • DataFrame.index, Series.index 로 객체 추출

  • 1차원 ndarray

# 원본 파일 재 로딩
titanic_df = pd.read_csv('titanic_train.csv')
# index 객체 추출
indexes = titanic_df.index
print(indexes)
# index 객체를 실제 값 array로 변환
RangeIndex(start=0, stop=891, step=1)
print(type(indexes.values))
print(indexes.values.shape)
print(indexes[:5].values)
print(indexes.values[:5])
print(indexes[6])
<class 'numpy.ndarray'>
(891,)
[0 1 2 3 4]
[0 1 2 3 4]
6
indexes[:5]
RangeIndex(start=0, stop=5, step=1)
# 값 변경 불가, 식별용으로만 사용
indexes[0] = 5
---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

<ipython-input-27-7a7ae340f897> in <module>
      1 # 값 변경 불가, 식별용으로만 사용
----> 2 indexes[0] = 5


C:\ProgramData\Anaconda3\envs\r_study\lib\site-packages\pandas\core\indexes\base.py in __setitem__(self, key, value)
   3908 
   3909     def __setitem__(self, key, value):
-> 3910         raise TypeError("Index does not support mutable operations")
   3911 
   3912     def __getitem__(self, key):


TypeError: Index does not support mutable operations
series_fair = titanic_df['Fare']
print('Fair Series max 값:', series_fair.max())
print('Fair Series sum 값:', series_fair.sum())
print('sum() Fair Series:', sum(series_fair))
print('Fair Series + 3:\n',(series_fair + 3).head(3) )
Fair Series max 값: 512.3292
Fair Series sum 값: 28693.9493
sum() Fair Series: 28693.949299999967
Fair Series + 3:
 0    10.2500
1    74.2833
2    10.9250
Name: Fare, dtype: float64
# reset_index() - index 새로 생성시, 연속된 index 아닐때 주로 사용
# 기존 index 삭제시는 drop=True 속성 사용
titanic_reset_df = titanic_df.reset_index()
# inplace=False
titanic_reset_df.head(3)
  index PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked
0 0 1 0 3 Braund, Mr. Owen Harris male 22.0 1 0 A/5 21171 7.2500 NaN S
1 1 2 1 1 Cumings, Mrs. John Bradley (Florence Briggs Th... female 38.0 1 0 PC 17599 71.2833 C85 C
2 2 3 1 3 Heikkinen, Miss. Laina female 26.0 0 0 STON/O2. 3101282 7.9250 NaN S
print('### before reset_index ###')
value_counts = titanic_df['Pclass'].value_counts()
print(value_counts)
print('value_counts 객체 변수 타입:',type(value_counts))

new_value_counts = value_counts.reset_index()
print('### After reset_index ###')
print(new_value_counts)
print('new_value_counts 객체 변수 타입:',type(new_value_counts))
### before reset_index ###
3    491
1    216
2    184
Name: Pclass, dtype: int64
value_counts 객체 변수 타입: <class 'pandas.core.series.Series'>
### After reset_index ###
   index  Pclass
0      3     491
1      1     216
2      2     184
new_value_counts 객체 변수 타입: <class 'pandas.core.frame.DataFrame'>

데이터 셀렉션 및 필터링

  • DataFrame의 [ ] 연산자

  • 컬럼 : [컬럼(리스트)] - ['Pclass']

  • 블린인덱스 : [[블린인덱스]] - [['Pclass' == 3]]

  • 슬라이싱연산 : [슬라이싱연산] - [0:3] 비추천

print('단일 컬럼 데이터 추출:\n', titanic_df[ 'Pclass' ].head(3))
# 여러개는 []에 넣어서 추출
print('\n여러 컬럼들의 데이터 추출:\n', titanic_df[ ['Survived', 'Pclass'] ].head(3))
# 오류
#print('[ ] 안에 숫자 index는 KeyError 오류 발생:\n', titanic_df[0])
단일 컬럼 데이터 추출:
 0    3
1    1
2    3
Name: Pclass, dtype: int64

여러 컬럼들의 데이터 추출:
    Survived  Pclass
0         0       3
1         1       1
2         1       3
titanic_df[0:2]
  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
titanic_df[titanic_df['Pclass'] == 3].head(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.250 NaN S
2 3 1 3 Heikkinen, Miss. Laina female 26.0 0 0 STON/O2. 3101282 7.925 NaN S
4 5 0 3 Allen, Mr. William Henry male 35.0 0 0 373450 8.050 NaN S
  • DataFrame ix[] 삭제됨

data = {'Name': ['Chulmin', 'Eunkyung','Jinwoong','Soobeom'],
        'Year': [2011, 2016, 2015, 2015],
        'Gender': ['Male', 'Female', 'Male', 'Male']
       }
data_df = pd.DataFrame(data, index=['one','two','three','four'])
data_df
  Name Year Gender
one Chulmin 2011 Male
two Eunkyung 2016 Female
three Jinwoong 2015 Male
four Soobeom 2015 Male

명칭 기반 인덱싱과 위치 기반 인덱싱의 구분

  • 명칭 기반 : 컬럼의 명칭 기반 위치 지정

  • 위치 기반 : 행, 열 기반 위치 지정

# data_df 를 reset_index() 로 새로운 숫자형 인덱스를 생성
data_df_reset = data_df.reset_index()
data_df_reset = data_df_reset.rename(columns={'index':'old_index'})
data_df_reset
  old_index Name Year Gender
0 one Chulmin 2011 Male
1 two Eunkyung 2016 Female
2 three Jinwoong 2015 Male
3 four Soobeom 2015 Male
# index 값에 1을 더해서 1부터 시작하는 새로운 index값 생성
data_df_reset.index = data_df_reset.index + 1
data_df_reset
  old_index Name Year Gender
1 one Chulmin 2011 Male
2 two Eunkyung 2016 Female
3 three Jinwoong 2015 Male
4 four Soobeom 2015 Male

DataFrame iloc[ ] 연산자

  • 위치(행, 열) 기반

data_df
  Name Year Gender
one Chulmin 2011 Male
two Eunkyung 2016 Female
three Jinwoong 2015 Male
four Soobeom 2015 Male
data_df.iloc[0, 0]
'Chulmin'
# 아래 코드는 오류를 발생합니다. 
# data_df.iloc[0, 'Name']
# data_df.iloc['one', 0]
data_df_reset.iloc[0, 1]
'Chulmin'

DataFrme loc[] 연산자

  • 명칭기반 [index값, 컬럼명]
data_df.loc['one', 'Name']
'Chulmin'
data_df_reset.loc[1, 'Name']
'Chulmin'
print('위치기반 iloc slicing\n', data_df.iloc[0:1, 0],'\n')
print('명칭기반 loc slicing\n', data_df.loc['one':'two', 'Name'])
위치기반 iloc slicing
 one    Chulmin
Name: Name, dtype: object 

명칭기반 loc slicing
 one     Chulmin
two    Eunkyung
Name: Name, dtype: object
# 명칭기반 loc에서는 마지막 값까지 가저옴(명칭 이므로)
print(data_df_reset.loc[1:2 , 'Name'])
1     Chulmin
2    Eunkyung
Name: Name, dtype: object

불린 인덱싱

  • 편리한 데이터 필터링 방식

  • 조건으로 원하는 값 필터링

  • loc에서 사용

titanic_df = pd.read_csv('titanic_train.csv')
titanic_boolean = titanic_df[titanic_df['Age'] > 60]
#print(type(titanic_boolean))
titanic_boolean
  PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked
33 34 0 2 Wheadon, Mr. Edward H male 66.0 0 0 C.A. 24579 10.5000 NaN S
54 55 0 1 Ostby, Mr. Engelhart Cornelius male 65.0 0 1 113509 61.9792 B30 C
96 97 0 1 Goldschmidt, Mr. George B male 71.0 0 0 PC 17754 34.6542 A5 C
116 117 0 3 Connors, Mr. Patrick male 70.5 0 0 370369 7.7500 NaN Q
170 171 0 1 Van der hoef, Mr. Wyckoff male 61.0 0 0 111240 33.5000 B19 S
252 253 0 1 Stead, Mr. William Thomas male 62.0 0 0 113514 26.5500 C87 S
275 276 1 1 Andrews, Miss. Kornelia Theodosia female 63.0 1 0 13502 77.9583 D7 S
280 281 0 3 Duane, Mr. Frank male 65.0 0 0 336439 7.7500 NaN Q
326 327 0 3 Nysveen, Mr. Johan Hansen male 61.0 0 0 345364 6.2375 NaN S
438 439 0 1 Fortune, Mr. Mark male 64.0 1 4 19950 263.0000 C23 C25 C27 S
456 457 0 1 Millet, Mr. Francis Davis male 65.0 0 0 13509 26.5500 E38 S
483 484 1 3 Turkula, Mrs. (Hedwig) female 63.0 0 0 4134 9.5875 NaN S
493 494 0 1 Artagaveytia, Mr. Ramon male 71.0 0 0 PC 17609 49.5042 NaN C
545 546 0 1 Nicholson, Mr. Arthur Ernest male 64.0 0 0 693 26.0000 NaN S
555 556 0 1 Wright, Mr. George male 62.0 0 0 113807 26.5500 NaN S
570 571 1 2 Harris, Mr. George male 62.0 0 0 S.W./PP 752 10.5000 NaN S
625 626 0 1 Sutton, Mr. Frederick male 61.0 0 0 36963 32.3208 D50 S
630 631 1 1 Barkworth, Mr. Algernon Henry Wilson male 80.0 0 0 27042 30.0000 A23 S
672 673 0 2 Mitchell, Mr. Henry Michael male 70.0 0 0 C.A. 24580 10.5000 NaN S
745 746 0 1 Crosby, Capt. Edward Gifford male 70.0 1 1 WE/P 5735 71.0000 B22 S
829 830 1 1 Stone, Mrs. George Nelson (Martha Evelyn) female 62.0 0 0 113572 80.0000 B28 NaN
851 852 0 3 Svensson, Mr. Johan male 74.0 0 0 347060 7.7750 NaN S
# 블린 인덱싱의 리턴 값은 DataFrame 이므로 원하는 컬럼만 추출 가능
titanic_df[titanic_df['Age'] > 60][['Name','Age']].head(3)
  Name Age
33 Wheadon, Mr. Edward H 66.0
54 Ostby, Mr. Engelhart Cornelius 65.0
96 Goldschmidt, Mr. George B 71.0
titanic_df.loc[titanic_df['Age'] > 60, ['Name','Age']].head(3)
  Name Age
33 Wheadon, Mr. Edward H 66.0
54 Ostby, Mr. Engelhart Cornelius 65.0
96 Goldschmidt, Mr. George B 71.0
# 논리연산 가능
# and : &, or : |, not : ~
titanic_df[(titanic_df['Age'] > 60) & (titanic_df['Pclass'] == 1) & (titanic_df['Sex']=='female')]
  PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked
275 276 1 1 Andrews, Miss. Kornelia Theodosia female 63.0 1 0 13502 77.9583 D7 S
829 830 1 1 Stone, Mrs. George Nelson (Martha Evelyn) female 62.0 0 0 113572 80.0000 B28 NaN
cond1 = titanic_df['Age'] > 60
cond2 = titanic_df['Pclass']==1
cond3 = titanic_df['Sex']=='female'
titanic_df[ cond1 & cond2 & cond3]
  PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked
275 276 1 1 Andrews, Miss. Kornelia Theodosia female 63.0 1 0 13502 77.9583 D7 S
829 830 1 1 Stone, Mrs. George Nelson (Martha Evelyn) female 62.0 0 0 113572 80.0000 B28 NaN

정렬, Aggregation 함수, GroupBy 적용

  • DataFrame, Series의 정렬 - sort_values() : order by

  • ascending=True 오름차순

  • inplace=False DataFrame 유지하면서 정렬된 데이터 리턴

  • inplace=True DataFrame에 정렬된 데이터 적용 됨, None 리턴

titanic_df.head(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
titanic_sorted = titanic_df.sort_values(by=['Name'])
titanic_sorted.head(3)
  PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked
845 846 0 3 Abbing, Mr. Anthony male 42.0 0 0 C.A. 5547 7.55 NaN S
746 747 0 3 Abbott, Mr. Rossmore Edward male 16.0 1 1 C.A. 2673 20.25 NaN S
279 280 1 3 Abbott, Mrs. Stanton (Rosa Hunt) female 35.0 1 1 C.A. 2673 20.25 NaN S
# 오름차순이 Default, 내림차순 하려면 ascending=False
titanic_sorted = titanic_df.sort_values(by=['Pclass', 'Name'], ascending=False)
titanic_sorted.head(3)
  PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked
868 869 0 3 van Melkebeke, Mr. Philemon male NaN 0 0 345777 9.5 NaN S
153 154 0 3 van Billiard, Mr. Austin Blyler male 40.5 0 2 A/5. 851 14.5 NaN S
282 283 0 3 de Pelsmaeker, Mr. Alfons male 16.0 0 0 345778 9.5 NaN S
  • Aggregation 함수 적용

titanic_df.count()
PassengerId    891
Survived       891
Pclass         891
Name           891
Sex            891
Age            714
SibSp          891
Parch          891
Ticket         891
Fare           891
Cabin          204
Embarked       889
dtype: int64
titanic_df[['Age','Fare']].mean()
Age     29.699118
Fare    32.204208
dtype: float64
  • groupby()

  • 그룹핑을 하면 집계 함수 사용

titanic_groupby = titanic_df.groupby('Pclass').count()
titanic_groupby
  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
type(titanic_groupby)
pandas.core.frame.DataFrame
# select count('PassengerId'), count('Survived') from titanic_df group by 'Pclass'
titanic_groupby = titanic_df.groupby('Pclass')[['PassengerId', 'Survived']].count()
titanic_groupby
  PassengerId Survived
Pclass    
1 216 216
2 184 184
3 491 491
# 적용 함수가 여러개 인경우 agg([함수명1, 함수명2,...])
titanic_df.groupby('Pclass')['Age'].agg([max, min])
  max min
Pclass    
1 80.0 0.92
2 70.0 0.67
3 74.0 0.42
# 컬럼처럼 만들거면 딕셔너리로 넣어줄것
agg_format={'Age':'max', 'SibSp':'sum', 'Fare':'mean'}
titanic_df.groupby('Pclass').agg(agg_format)
  Age SibSp Fare
Pclass      
1 80.0 90 84.154687
2 70.0 74 20.662183
3 74.0 302 13.675550

결손 데이터 처리하기

  • Null 값 / NaN

  • 계산 함수 연산시 자동 제외 됨

  • isna()로 결손 데이터 여부 확인 : 결손 시 True

# isna() = isnull() 둘 다 같음
titanic_df.isna().head(3)
  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
# True : 1 의 합
titanic_df.isna().sum()
PassengerId      0
Survived         0
Pclass           0
Name             0
Sex              0
Age            177
SibSp            0
Parch            0
Ticket           0
Fare             0
Cabin          687
Embarked         2
dtype: int64
  • fillna()로 Misiing 데이터 대체하기

# 반환받아 다시 넣거나 fillna('값', inplace=True)
titanic_df['Cabin'] = titanic_df['Cabin'].fillna('C000')
titanic_df.head(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 C000 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 C000 S
# 평균값으로 처리
titanic_df['Age'] = titanic_df['Age'].fillna(titanic_df['Age'].mean())
titanic_df['Embarked'] = titanic_df['Embarked'].fillna('S')
titanic_df.isna().sum()
PassengerId    0
Survived       0
Pclass         0
Name           0
Sex            0
Age            0
SibSp          0
Parch          0
Ticket         0
Fare           0
Cabin          0
Embarked       0
dtype: int64

apply lambda 식으로 데이터 가공

  • R의 sapply(), tapply()

  • Python의 map()

def get_square(a):
    return a**2

print('3의 제곱은:',get_square(3))
3의 제곱은: 9
lambda_square = lambda x : x ** 2
print('3의 제곱근은 :', lambda_square(3))
3의 제곱근은 : 9
a = [1, 2, 3]
squares = map(lambda x : x ** 2, a)
list(squares)
[1, 4, 9]
titanic_df['Name_len'] = titanic_df['Name'].apply(lambda x : len(x))
titanic_df[['Name', 'Name_len']].head(3)
  Name Name_len
0 Braund, Mr. Owen Harris 23
1 Cumings, Mrs. John Bradley (Florence Briggs Th... 51
2 Heikkinen, Miss. Laina 22
titanic_df['Child_Adult'] = titanic_df['Age'].apply(lambda x : 'Child' if x<=15 else 'Adult')
titanic_df[['Age', 'Child_Adult']].head(8)
  Age Child_Adult
0 22.000000 Adult
1 38.000000 Adult
2 26.000000 Adult
3 35.000000 Adult
4 35.000000 Adult
5 29.699118 Adult
6 54.000000 Adult
7 2.000000 Child
titanic_df['Age_cat'] = titanic_df['Age'].apply(lambda x : 'Child' if x<=15 else('Adult' if x<= 60 else 'Elderly'))
titanic_df['Age_cat'].value_counts()
Adult      786
Child       83
Elderly     22
Name: Age_cat, dtype: int64
# 나이에 따라 세분화된 분류를 수행하는 함수 생성.
def get_category(age):
    cat=''
    if age <= 5: cat = 'Baby'
    elif age <= 12: cat = 'Child'
    elif age <= 18: cat = 'Teenager'
    elif age <= 25: cat = 'Student'
    elif age <= 35: cat = 'Young Adult'
    elif age <= 60: cat = 'Adult'
    else : cat = 'Elderly'

    return cat

# lambda 식에 위에서 생성한 get_category() 함수를 반환값으로 지정
# get_category(X)는 입력값으로 'Age' 컬럼 값을 받아서 해당하는 cat 반환
titanic_df['Age_cat'] = titanic_df['Age'].apply(lambda x : get_category(x))
titanic_df[['Age', 'Age_cat']].head()
  Age Age_cat
0 22.0 Student
1 38.0 Adult
2 26.0 Young Adult
3 35.0 Young Adult
4 35.0 Young Adult

Pandas.html
0.40MB