!kaggle competitions download -c titanic
Warning: Looks like you're using an outdated API Version, please consider updating (server 1.5.12 / client 1.5.4)
train.csv: Skipping, found more recently modified local copy (use --force to force download)
test.csv: Skipping, found more recently modified local copy (use --force to force download)
gender_submission.csv: Skipping, found more recently modified local copy (use --force to force download)

두 번째 파트에서는 Pandas의 기술 통계 함수들과 집계함수(aggregation funtion) 그리고 피벗 테이블(Pivot table)에 대해 알아 보겠습니다.

Summary

  • .median(): 중앙값 , mode(): 최고 빈도수
  • .min(): 최솟값 , .max(): 최댓값
  • .var(): 분산, .std(): 표준편차
  • .sum(): 합계
  • quantile(): 백분위수
age=df['Age']
age.describe()
count    714.000000
mean      29.699118
std       14.526497
min        0.420000
25%       20.125000
50%       28.000000
75%       38.000000
max       80.000000
Name: Age, dtype: float64

describe() 함수를 이용해서 간단하게 보면 타이타닉 나이대에 대한 통계를 확인할 수 있습니다. 직접 확인해 보겠습니다

print('중앙값: ',age.median())
print('최빈수값: ',age.mode())
print('최솟값: ',age.min())
print('최댓값: ',age.max())
print('분산: ',age.var())
print('표준편차: ',age.std())
print('합계: ',age.sum())
print('백분위수 중 0.5: ',age.quantile(0.5))
중앙값:  28.0
최빈수값:  0    24.0
dtype: float64
최솟값:  0.42
최댓값:  80.0
분산:  211.0191247463081
표준편차:  14.526497332334044
합계:  21205.17
백분위수 중 0.5:  28.0

위의 describe()함수를 사용했던 결과값과 동일한 것을 확인할 수 있습니다.

누적 통계(Cumulative statistics)

  • .cummax()
  • .cummin()
  • .cumprod()

Counting

  • .value_counts()
  • .value_counts(sort=True)
  • .value_counts(normalize=True)

Dropping duplicate(중복제거)

  • .drop_duplicates(subset="컬럼명")
  • .drop_duplicates(subset=["컬럼명", "컬럼명"])
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

Pclass에 대해서 한 번 실습을 진행해보겠습니다.

df['Pclass'].value_counts()
3    491
1    216
2    184
Name: Pclass, dtype: int64
df['Pclass'].value_counts(sort=True)
3    491
1    216
2    184
Name: Pclass, dtype: int64
df['Pclass'].value_counts(normalize=True)
3    0.551066
1    0.242424
2    0.206510
Name: Pclass, dtype: float64

결과를 보다시피 기본적으로 정렬이 되어있으며 normalize 옵션을 True로 해줄 경우 개수가 아닌 0~1 사이의 값으로 변환된 것을 확인할 수 있습니다.
Pclass ==3 은 전체 중 55.1%를 차지하고 있습니다

Grouping

다음은 Groupby() 함수에 대해서 알아보겠습니다.
Group by 함수는 특정 컬럼을 기준으로 그룹화를 도와주는 함수입니다.
그룹화된 함수에 통계 함수 또한 사용이 가능합니다.

Pclass를 기준으로 하여 데이터 프레임을 생성합니다

gb_class=df.groupby('Pclass')

그룹만 만들었다고 바로 볼 수 없습니다.

for key, group in gb_class:
    print("* key", key)
    print("* count", len(group))
    print(group.head())
    print('\n')
* key 1
* count 216
    PassengerId  Survived  Pclass  ...     Fare Cabin  Embarked
1             2         1       1  ...  71.2833   C85         C
3             4         1       1  ...  53.1000  C123         S
6             7         0       1  ...  51.8625   E46         S
11           12         1       1  ...  26.5500  C103         S
23           24         1       1  ...  35.5000    A6         S

[5 rows x 12 columns]


* key 2
* count 184
    PassengerId  Survived  Pclass  ...     Fare Cabin  Embarked
9            10         1       2  ...  30.0708   NaN         C
15           16         1       2  ...  16.0000   NaN         S
17           18         1       2  ...  13.0000   NaN         S
20           21         0       2  ...  26.0000   NaN         S
21           22         1       2  ...  13.0000   D56         S

[5 rows x 12 columns]


* key 3
* count 491
   PassengerId  Survived  Pclass  ...     Fare Cabin  Embarked
0            1         0       3  ...   7.2500   NaN         S
2            3         1       3  ...   7.9250   NaN         S
4            5         0       3  ...   8.0500   NaN         S
5            6         0       3  ...   8.4583   NaN         Q
7            8         0       3  ...  21.0750   NaN         S

[5 rows x 12 columns]


여기서 각 그룹의 정보를 가져올려면 get_group() 함수를 사용하면 됩니다

gb_class.get_group(1).head()
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
11 12 1 1 Bonnell, Miss. Elizabeth female 58.0 0 0 113783 26.5500 C103 S
23 24 1 1 Sloper, Mr. William Thompson male 28.0 0 0 113788 35.5000 A6 S

위에서 말씀드린 것처럼 그룹화 이후 통계함수를 사용할 수 있다고 했는데 바로 사용해보도록 하겠습니다

gb_class.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')['SibSp'].agg([min, max, sum])
min max sum
Pclass
1 0 3 90
2 0 3 74
3 0 8 302

위 코드는 Pclass를 기준으로 형제자매 수에 대해 min, max, sum 함수를 사용한 것입니다.
3가지 클래스 모두 최솟값은 0이며 Plcass 3의 최댓값이 8인 것을 확인할 수 있습니다. 또한 sum 함수의 결과로 클래스 3에 가장 많은 사람이 몰려 있는 것을 확인할 수 있습니다.

추가로 groupby를 할 때 기준 열을 두 개로도 지정이 가능합니다.

df.groupby(['Pclass','Sex']).mean()
PassengerId Survived Age SibSp Parch Fare
Pclass Sex
1 female 469.212766 0.968085 34.611765 0.553191 0.457447 106.125798
male 455.729508 0.368852 41.281386 0.311475 0.278689 67.226127
2 female 443.105263 0.921053 28.722973 0.486842 0.605263 21.970121
male 447.962963 0.157407 30.740707 0.342593 0.222222 19.741782
3 female 399.729167 0.500000 21.750000 0.895833 0.798611 16.118810
male 455.515850 0.135447 26.507589 0.498559 0.224784 12.661633

이렇게 두 가지 기준열을 넣음으로써 클래스별 남녀에 따른 값을 확인할 수 있습니다.
생존에 대해 봤을 때 클래스 1, 2의 여자 생존률은 매우 높은 반면 남자는 매우 낮은 것을 확인할 수 있습니다. 그리고 아까 클래스 3에 사람이 많다고 했었죠? 클래스 3의 여자 생존률은 왜 1, 2에 비해 낮은지도 확인해 볼 필요가 있습니다

Pivot table

마지막으로 피벗 테이블 입니다.
pivot_table() 함수의 기본 구성요소는 다음과 같습니다

  • index: 행 인덱스
  • columns: 열 인덱스
  • values: 데이터로 사용할 값
  • aggfunc: 데이터 집계함수

groupby와 한번 비교해 보겠습니다

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.pivot_table(index='Pclass', aggfunc=np.mean)
Age Fare Parch PassengerId SibSp Survived
Pclass
1 38.233441 84.154687 0.356481 461.597222 0.416667 0.629630
2 29.877630 20.662183 0.380435 445.956522 0.402174 0.472826
3 25.140620 13.675550 0.393075 439.154786 0.615071 0.242363

열의 순서가 좀 다르긴 하지만 내용은 두 가지 모두 같습니다.
Group by 함수 결과와 똑같이 만드는 것을 연습해 보신다면 도움이 많이 될 것 같습니다

df.groupby(['Pclass','Sex']).mean()
PassengerId Survived Age SibSp Parch Fare
Pclass Sex
1 female 469.212766 0.968085 34.611765 0.553191 0.457447 106.125798
male 455.729508 0.368852 41.281386 0.311475 0.278689 67.226127
2 female 443.105263 0.921053 28.722973 0.486842 0.605263 21.970121
male 447.962963 0.157407 30.740707 0.342593 0.222222 19.741782
3 female 399.729167 0.500000 21.750000 0.895833 0.798611 16.118810
male 455.515850 0.135447 26.507589 0.498559 0.224784 12.661633
df.pivot_table(index=['Pclass','Sex'], aggfunc=np.mean)
Age Fare Parch PassengerId SibSp Survived
Pclass Sex
1 female 34.611765 106.125798 0.457447 469.212766 0.553191 0.968085
male 41.281386 67.226127 0.278689 455.729508 0.311475 0.368852
2 female 28.722973 21.970121 0.605263 443.105263 0.486842 0.921053
male 30.740707 19.741782 0.222222 447.962963 0.342593 0.157407
3 female 21.750000 16.118810 0.798611 399.729167 0.895833 0.500000
male 26.507589 12.661633 0.224784 455.515850 0.498559 0.135447

여기서 조금 더 추가해서 나이에 대해 깊게 파보겠습니다

df.pivot_table(index=['Pclass','Sex'], values='Age',aggfunc=[np.mean, np.max, np.min])
mean amax amin
Age Age Age
Pclass Sex
1 female 34.611765 63.0 2.00
male 41.281386 80.0 0.92
2 female 28.722973 57.0 2.00
male 30.740707 70.0 0.67
3 female 21.750000 63.0 0.75
male 26.507589 74.0 0.42
df.pivot_table(index='Sex', columns='Pclass', values='Survived', aggfunc=np.mean)
Pclass 1 2 3
Sex
female 0.968085 0.921053 0.500000
male 0.368852 0.157407 0.135447

추가 옵션이 두 가지 있습니다

  • fill_value
  • margins=True

fill_value는 결측값을 대체해주는 역할을 합니다 fill_value=0으로 두신 다면 결측값들은 0으로 대체 됩니다.
margins는 마지막에 전체 집계결과를 보여줍니다.

df.pivot_table(index='Sex', columns='Pclass', values='Survived', aggfunc=np.mean, margins=True)
Pclass 1 2 3 All
Sex
female 0.968085 0.921053 0.500000 0.742038
male 0.368852 0.157407 0.135447 0.188908
All 0.629630 0.472826 0.242363 0.383838