유승훈

Python(1) - Basic Data attribute 본문

languages/Python

Python(1) - Basic Data attribute

seunghuni96 2020. 3. 5. 16:34

Datacamp에서 들은 강의에 대한 공부내용입니다.

1차적으로 강의에 나온 내용만 정리해두고, 자세하게 공부한 내용을 추가적으로 업데이트할 예정입니다.

 

데이터 전처리는 중요합니다. 데이터가 언제나 깔끔하고 이쁜 형태로 온다는 보장은 없기 때문이죠.

Column name이 이상할수도 있고, 데이터가 없거나 나올수없는 값이 있을수도 있습니다. 그 외에도 중복값, 이상치 등 데이터 전처리에서는 많은 것들을 다룹니다. 이런 전처리를 하기 전에, 우리는 데이터가 어떻게 생겼는지를 들여다 볼 필요가 있습니다. 모양을 알아야 주물러서 우리가 다루기 편하게 변형할수있기 때문이죠.

 

1. head, tail, columns, shape, info

 

처음 데이터를 다룰때 가장 많이 쓰이곤 하는 Titanic dataset을 가져왔습니다. 승객들의 데이터로 생존여부를 예측하는 문제입니다.

aa = 'C:/Users/rsh15/Downloads/titanic_train.csv'
df = pd.read_csv(aa)


print(df.head())
   PassengerId  Survived  Pclass  ...     Fare Cabin  Embarked
0            1         0       3  ...   7.2500   NaN         S
1            2         1       1  ...  71.2833   C85         C
2            3         1       3  ...   7.9250   NaN         S
3            4         1       1  ...  53.1000  C123         S
4            5         0       3  ...   8.0500   NaN         S

print(df.tail())
     PassengerId  Survived  Pclass  ...   Fare Cabin  Embarked
886          887         0       2  ...  13.00   NaN         S
887          888         1       1  ...  30.00   B42         S
888          889         0       3  ...  23.45   NaN         S
889          890         1       1  ...  30.00  C148         C
890          891         0       3  ...   7.75   NaN         Q

데이터를 불러오면 가장 먼저 개괄적인 내용들을 볼 필요가 있습니다. 이때 가장 단순하게 head와 tail 메소드를 활용할수있습니다.

head는 데이터의 첫 5행을, tail은 데이터의 마지막 5행을 보여줍니다. 기본적으로 print하는 행이 5개인것이고, 인수를 통해 출력할 행의 수를 정할 수 있습니다.

print(df.head(3))
   PassengerId  Survived  Pclass  ...     Fare Cabin  Embarked
0            1         0       3  ...   7.2500   NaN         S
1            2         1       1  ...  71.2833   C85         C
2            3         1       3  ...   7.9250   NaN         S

print(df.tail(10))
     PassengerId  Survived  Pclass  ...     Fare Cabin  Embarked
881          882         0       3  ...   7.8958   NaN         S
882          883         0       3  ...  10.5167   NaN         S
883          884         0       2  ...  10.5000   NaN         S
884          885         0       3  ...   7.0500   NaN         S
885          886         0       3  ...  29.1250   NaN         Q
886          887         0       2  ...  13.0000   NaN         S
887          888         1       1  ...  30.0000   B42         S
888          889         0       3  ...  23.4500   NaN         S
889          890         1       1  ...  30.0000  C148         C
890          891         0       3  ...   7.7500   NaN         Q

인수에는 양수뿐 아니라 음수도 넣어줄수있습니다. 음수를 넣으면 그만큼의 행을 제외하고 출력합니다. tail(-5)는 첫5행을 제외한 데이터를, head(-10)은 밑10행을 제외한 모든 행을 출력한 결과를 볼수있습니다.  

df.tail(-5)
     PassengerId  Survived  Pclass  ...     Fare Cabin  Embarked
5              6         0       3  ...   8.4583   NaN         Q
6              7         0       1  ...  51.8625   E46         S
7              8         0       3  ...  21.0750   NaN         S
8              9         1       3  ...  11.1333   NaN         S
9             10         1       2  ...  30.0708   NaN         C
..           ...       ...     ...  ...      ...   ...       ...
886          887         0       2  ...  13.0000   NaN         S
887          888         1       1  ...  30.0000   B42         S
888          889         0       3  ...  23.4500   NaN         S
889          890         1       1  ...  30.0000  C148         C
890          891         0       3  ...   7.7500   NaN         Q
[886 rows x 12 columns]

df.head(-10)
     PassengerId  Survived  Pclass  ...     Fare Cabin  Embarked
0              1         0       3  ...   7.2500   NaN         S
1              2         1       1  ...  71.2833   C85         C
2              3         1       3  ...   7.9250   NaN         S
3              4         1       1  ...  53.1000  C123         S
4              5         0       3  ...   8.0500   NaN         S
..           ...       ...     ...  ...      ...   ...       ...
876          877         0       3  ...   9.8458   NaN         S
877          878         0       3  ...   7.8958   NaN         S
878          879         0       3  ...   7.8958   NaN         S
879          880         1       1  ...  83.1583   C50         C
880          881         1       2  ...  26.0000   NaN         S
[881 rows x 12 columns]

이외에도 데이터의 열 이름들을 columns 속성을 통해 살펴볼수있고, shape로 데이터의 모양(행,열)을, info로 Column이 담고있는 데이터의 유형과 Null값을 가지고 있는지의 여부를 볼 수 있습니다.

df.columns
Index(['PassengerId', 'Survived', 'Pclass', 'Name', 'Sex', 'Age', 'SibSp',
       'Parch', 'Ticket', 'Fare', 'Cabin', 'Embarked'],dtype='object')
   
df.shape
(891, 12)

df.info
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 891 entries, 0 to 890
Data columns (total 12 columns):
PassengerId    891 non-null int64
Survived       891 non-null int64
Pclass         891 non-null int64
Name           891 non-null object
Sex            891 non-null object
Age            714 non-null float64
SibSp          891 non-null int64
Parch          891 non-null int64
Ticket         891 non-null object
Fare           891 non-null float64
Cabin          204 non-null object
Embarked       889 non-null object
dtypes: float64(2), int64(5), object(5)
memory usage: 66.2+ KB

 

2. value_counts, describe

 

수치형이 아니라 그룹형태를 가지고 있는 변수는 각각의 값에 대한 빈도를 볼 필요가 있습니다. 이는 value_counts를 통해 볼 수 있습니다.

df.Pclass.value_counts()
3    491
1    216
2    184
Name: Pclass, dtype: int64

이렇게 race 컬럼에 들어있는 각각의 데이터에 대한 빈도를 value_counts를 통해 볼 수 있습니다. 옵션으로는 NULL값을 넣고셀지 빼고셀지를 선택할 수 있습니다. dropna가 기본적으로는 True로 NaN을 세지 않지만, False를 넣어주면 NaN까지 센 결과를 출력해줍니다. 다음으로 normalize를 보면 전체 개수가 아닌 비율로 데이터를 살펴볼수있습니다. 마지막으로 bin은 그룹이 아닌 수치형 데이터에 활용됩니다. 나이 같은 수치형데이터를 bin옵션을 통해 그룹화한 관측치를 볼수있습니다.

df.Embarked.value_counts()
S    644
C    168
Q     77
Name: Embarked, dtype: int64


df.Embarked.value_counts(dropna=False)
S      644
C      168
Q       77
NaN      2
Name: Embarked, dtype: int64


df.Embarked.value_counts(normalize=True)
S    0.724409
C    0.188976
Q    0.086614
Name: Embarked, dtype: float64


df.Age.value_counts(bins=5)
(16.336, 32.252]    346
(32.252, 48.168]    188
(0.339, 16.336]     100
(48.168, 64.084]     69
(64.084, 80.0]       11
Name: Age, dtype: int64

 

3. Visual EDA(Histogram, Boxplot, Scatterplot)

 

위에서 소개해드렸던 수치상의 탐색 외에도 우리는 간단한 시각화를 통해서 데이터를 들여다볼 수 있습니다. R에는 ggplot2라는 시각화 패키지를 거의 대부분 쓰지만, Python에는 다양한 시각화 패키지가 있다고 합니다. 그 중에서도 matplotlib이 많이 쓰인다고 합니다.

 

df['age'].plot(kind = 'hist')

Age 컬럼의 히스토그램

이렇게 간단한 히스토그램의 형태입니다. 히스토그램을 통해서는 데이터가 얼마나 한쪽으로 치우쳐있는지, 중심(평균)에 얼마나 모여있는가를 시각적으로 확인해볼수있습니다. 데이터가 치우친 정도는 왜도(Skewness), 데이터가 중심에 모여있는 정도는 첨도(Kurtosis)라는 통계량이 있습니다.

 

왜도가 커질수록 데이터가 왼쪽으로 모이면서 오른쪽으로 긴 꼬리를 갖게 되고, 반대로 작아질수록 데이터가 오른쪽으로 모이면서 왼쪽으로 긴 꼬리를 갖게 됩니다. 첨도는 커질수록 데이터가 중심(평균)으로 모이게 되면서 양쪽으로 짧은 꼬리를 갖게 되고, 중심에서 뾰족한 모양을 갖게 됩니다. 그리고 작아질수록 중심(평균)보다는 양쪽으로 데이터가 많이 분포하고, 중심은 낮고 원만하며 양쪽으로 긴 꼬리를 가진 모양을 갖게 됩니다.

 

df.boxplot(column = 'age',by = 'income_condition')

 

Titanic 데이터에서 종속변수인 생존여부(Survived)별로 나이(Age)의 Boxplot을 그린 그림입니다.

df.plot(kind = 'scatter',x = 'age',y = 'hours_per_week',alpha = 0.3)

다음은 산점도(Scatter plot)입니다. 이런식으로 한 row를 점 하나로 Plot에 흩뿌려 볼 수 있습니다. 산점도는 데이터가 너무 많으면 색이 너무 짙어져서 제대로된 탐색이 어렵기 때문에 점의 투명도를 옵션(alpha)으로 변경해줄수있습니다.

Comments