Pandas Overview

CharliePark·2020년 8월 26일
0

TIL

목록 보기
12/67

권철민 선생님의 <파이썬 머신러닝 완벽 가이드> 책과 강의를 통해 공부하며 정리한 내용입니다.
/ 강의

(파이썬 머신러닝 완벽 가이드 Chap 01.04)

 

판다스는 행(row)과 열(column)으로 이루어진 2차원 데이터를 효율적으로 가공/처리할 수 있는 기능 제공.

(특히 시계열 데이터를 다루는 데 아주 효과적이다.)

RDBMS나 SQL이나 엑셀 시트만큼은 아닐지라도, 이에 버금가는 고수준 API와 편의성을 제공.

리스트, 컬렉션, 넘파이 등의 파이썬 내부 데이터와 CSV 등의 외부 데이터를 DataFrame 으로 변경해 가공/분석을 편리하게 수행할 수 있다.

판다스의 핵심 객체는 DataFrame이다. DataFrame은 여러개의 열과 행으로 이뤄진 2차원 데이터를 담는 데이터 구조체이다. DataFrame은 NumPy의 ndarray로 만들어져 있다.

 

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

Series와 DataFrame은 모두 Index를 Key값으로 가지고 있으나, Series는 칼럼이 하나뿐이고, DataFrame은 칼럼이 여러개이다.

따라서, DataFrame은 여러개의 Series로 이뤄졌다고 생각할 수 있다.

(명확히는, series에는 column 이름이 없다)

 

판다스 시작 - 파일을 DataFrame으로 로딩, 기본 API

pandaspd 로 alias해 임포트하는 것이 관례이다.

 

import pandas as pd

 

딕셔너리를 DataFrame으로 변환해보자

dic1 = {'Name': ['Charlie', 'Harry', 'John', 'Anne'],
        'Year': [2011, 2015, 1999, 2004],
        'Gender': ['Male', 'Male', 'Male', 'Female']}

# 딕셔너리를 DataFrame으로 변환
data_df = pd.DataFrame(dic1)
print(data_df)
print('#'*30)

# 새로운 칼럼명을 추가
data_df = pd.DataFrame(dic1, columns = ['Name', 'Year', 'Gender', 'Age'])
print(data_df)
print('#'*30)

# 인덱스를 새로운 값으로 할당
data_df = pd.DataFrame(dic1, index = ['one', 'two', 'three', 'four'])
print(data_df)
print('#'*30)

output

      Name  Year  Gender
0  Charlie  2011    Male
1    Harry  2015    Male
2     John  1999    Male
3     Anne  2004  Female
##############################
      Name  Year  Gender  Age
0  Charlie  2011    Male  NaN
1    Harry  2015    Male  NaN
2     John  1999    Male  NaN
3     Anne  2004  Female  NaN
##############################
          Name  Year  Gender
one    Charlie  2011    Male
two      Harry  2015    Male
three     John  1999    Male
four      Anne  2004  Female
##############################

 

 

 

다양한 포맷으로 된 파일을 DataFrame 으로 로딩할 수 있는 편리한 API를 제공한다.

read_csv(), read_table(), read_fwf() 를 이용하면 DataFrame으로 변환할 수 있다.

 

read_csv() 는 CSV 파일(칼럼을 ','로 구분)을 포함하여, 어떤 필드 구분 문자(Delimeter) 기반의 파일 포맷도 DataFrame으로 변환이 가능하다.

read_csv() 의 인자인 sep에 해당 구분 문자를 입력하면 된다.

read_table() 은 '\t'을 구분 문자로 쓰는 파일을 변환해준다.

read_csv()read_table() 은 큰 차이가 없으므로 read_csv() 만 사용해도 무방하다.

 

read_fwf() 는 Fixed Width, 즉 고정 길이 기반의 칼럼 포맷을 DataFrame으로 로딩하기 위한 API이다.

 

read_csv(filepath_or_buffer, sep = ',', ...) 함수에서 가장 중요한 인자는 filepath 이다.

Filepath 에는 로드하려는 데이터 파일의 경로를 포함한 파일명을 입력하면 된다.

동일한 경로 내의 파일이라면 파일명 만으로 충분하다.

 

 

titanic_df = pd.read_csv('titanic_train.csv')
print('titanic 변수 type:',type(titanic_df))
titanic_df.head(3) # 일부만 출력
#titanic_df # 전체 출력

output

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

 

 

pd.read_csv()는 호출시 파일명 인자로 들어온 파일을 로딩해 DataFrame 객체로 반환한다.

이때, 별다른 파라미터 지정이 없으면 파일의 맨 처음 로우를 칼럼명으로 인지하고 칼럼으로 변환한다.

출력결과의 맨 왼쪽을 보면, 파일에 기재되 있지 않은 값이, 0, 1, 2, 3 이런 식으로 표시되는데, 이는 판다스의 Index 값이다.

모든 DataFrame 내의 데이터는 생성되는 순간 고유의 Index 값을 가지게 되고, 이는 RDBMS의 PK와 유사하게 고유의 레코드를 식별하는 역할이다.

 

 

 

DataFrame의 크기를 알아보기 위해서는 생성된 DataFrame 객체의 shape 변수를 이용하면 된다.

shape는 DataFrame 의 행과 열을 튜플로 반환한다.

 

print('DataFrame 크기: ', titanic_df.shape)

output

DataFrame 크기:  (891, 12)

 

 

DataFrame 은 데이터뿐만 아니라 칼럼의 타입, Null 데이터 개수, 데이터 분포도 등의 메타 데이터등도 조회가 가능하다.

이때 info()describe() 라는 메서드를 사용할 수 있다.

 

 

titanic_df.info()

output

<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: 83.7+ KB

info() 메서드를 통해서 총 데이터 건수와 데이터 타입, Null 건수를 알 수 있다.

 

 

 

describe() 메서드는 칼럼별 숫자형 데이터값의 n-percentile 분포도, 평균값, 최댓값, 최솟값을 나타낸다.

describe() 메서드는 오직 숫자형(int, float 등) 칼럼의 분포도만 조사하며 자동으로 object 타입의 칼럼은 출력에서 제외시킨다.

titanic_df.describe()

output

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

출력을 살펴보자.

count는 Not Null 인 데이터 건수, mean은 전체 데이터의 평균값, std는 표준편차, min과 max는 각각 최솟값과 최댓값이다.

25%, 50%, 75%는 각각의 percentile 값(백분위 25, 50, 75에 해당하는 값) 이다.

describe() 를 사용하면, 해당 숫자 칼럼이 숫자형 카테고리 칼럼인지 확인할 수 있다.

 

카테고리 칼럼은 특정 범주에 속하는 값을 코드화한 칼럼이다.

예컨대, 성별 칼럼에 '남' 과 '여'가 있다고 가정하면, 이를 '1', '2'와 같은 식으로 코드화한 칼럼이 카테고리 칼럼인 것이다.

아래 설명을 통해 차근히 이해해보자.

 

위 출력에서 PassengerID칼럼은 승객 ID를 식별하는 칼럼이므로 1~891까지 숫자가 할당되어서 분석을 위한 의미있는 속성이 아니다.

Survived의 경우 min은 0, 25~50%도 0, 75%는 1, max도 1이므로 0과 1로 이뤄진 숫자형 카테고리 칼럼일 것이다.

Pclass 칼럼은 min이 1, 25%가 2, 50~75%와 max가 3이므로 1, 2, 3으로 이뤄진 숫자형 카테고리 칼럼일 것이다.

Pclass 칼럼의 분포를 살펴보자.

DaraFrame의 [ ] 연산자 내부에 칼럼명을 입력하면 Series 형태로 칼럼 데이터 세트가 반환된다.

여기에 value_counts() 메서드를 호출하면 해당 칼럼값의 유형과 건수를 확인할 수 있다.

이때 value_counts() 메서드는 지정된 칼럼의 데이터값 건수를 반환한다.

 

titanic_pclass = titanic_df['Pclass']
print(titanic_pclass, '\n')
print(type(titanic_pclass), '\n')

value_counts = titanic_df['Pclass'].value_counts()
print(value_counts)

output

0      3
1      1
2      3
3      1
4      3
      ..
886    2
887    1
888    3
889    1
890    3
Name: Pclass, Length: 891, dtype: int64 

<class 'pandas.core.series.Series'> 

3    491
1    216
2    184
Name: Pclass, dtype: int64

Pclass값 3이 491개, 1이 216개, 2가 184개 이다. (내림차순 정렬)

Series는 Index와 단 하나의 칼럼으로 구성된 데이터 세트이다.

왼쪽에는 DataFrame의 Index와 동일한 Index,오른쪽에는 Series의 해당 칼럼의 데이터 값이다.

방금 사용한 value_counts() 메서드는 Series 객체에서만 정의되어있다.

 

value_counts() 메서드의 반환 데이터 타입과 반환값을 다시 확인해보자

value_counts = titanic_df['Pclass'].value_counts()
print(type(value_counts))
print(value_counts)

output

<class 'pandas.core.series.Series'>
3    491
1    216
2    184
Name: Pclass, dtype: int64

value_counts() 메서드의 반환 데이터 타입 역시 Series 객체이다.

이 역시 왼쪽이 Index, 오른쪽이 데이터값인데, 인덱스가 순차값이 아니다.

즉, 인덱스는 고유성만 보장된다면 의미있는 값을 할당하는 것도 가능하다.

고유 칼럼 값을 식별자로 사용할 수 있고, 이를 이용해 인덱스를 변경할 수도 있다. (숫자형뿐만 아니라 문자열도 가능)

0개의 댓글