[ESSA 2주차 과제]파머완 1-4장_판다스
판다스(Pandas)란?
- 파이썬에서 데이터 처리를 위해 존재하는 가장 인기 있는 라이브러리
- 행(row)과 열(column)로 구성된 2차원 데이터를 효율적으로 가공/처리하는 데 활용
- 파이썬의 리스트, 컬렉션, 넘파이 등의 내부 데이터뿐만 아니라 csv 등의 파일을 쉽게 DataFrame으로 변경해 데이터의 가공/분석을 편리하게 수행할 서 있게 해줌
- 데이터프레임(DataFrame)
- 여러 개의 행과 열로 이뤄진 2차원 데이터
- Index: RDBMS의 PK처럼 개별 데이터를 고유하게 식별하는 key값
- Series: 칼럼이 하나인 데이터 구조체
- DataFrame은 여러 개의 Series로 이뤄졌다고 할 수 있음
1. 판다스 시작 - 파일을 DataFrame으로 로딩, 기본 API
● 판다스 모듈 import
import pandas as pd
● 파일을 열기 위한 API
read_csv(filepath, sep = ',', ...)
- csv(칼럼을 ‘,’로 구분한 파일 포맷) 파일 포맷 변환
- 파일을 로딩해 DataFrame 객체로 반환
- csv 뿐만 아니라 어떤 필드 구분 문자 기반의 파일 포맷도 변환 가능
sep
인자를 통해 필드 구분 문자(delimeter) 지정
- 파이썬 실행 파일이 있는 디렉터리와 동일한 디렉터리에 파일이 있는 경우 filepath에 파일명만 입력해도 ok
- 별다른 파라미터 지정이 없으면 파일의 맨 처음 row를 칼럼명으로 활용
- csv(칼럼을 ‘,’로 구분한 파일 포맷) 파일 포맷 변환
read_table()
: 칼럼을 탭(‘\t’)으로 구분한 파일 포맷) 파일 포맷 변환read_fwf()
: 고정 길이 기반의 칼럼 포맷을 DataFrame으로 로딩
● 데이터 표시/확인
pd.DataFrame.head(n)
: 맨 앞에 있는 n개의 row 반환(default = 5)pd.DataFrame.shape
: DataFrame의 행과 열을 튜플 형태로 반환pd.DataFrame.info()
: 칼럼의 타입, Null 데이터 개수, 데이터 분포도 등의 메타 데이터 확인- RangeIndex: DataFrame의 index 범위 => 전체 행의 개수 파악 가능
- dtypes: 데이터 칼럼들의 타입을 요약한 것
pd.DataFrame.describe()
:- 칼럼별 숫자형 데이터값의 n-percentile 분포도, 평균값, 최댓값, 최솟값 등을 나타냄
- 오직 숫자형(int, float 등) 칼럼의 분포도만 조사함
- 개략적인 수준의 분포도를 확인할 수 있음
- 특정 컬럼이 숫자형 카테고리 칼럼인지를 판단하는 데 도움을 줌
- count: Not Null인 데이터 건수
Series 객체
- Index와 단 하나의 컬럼으로 구성된 데이터 세트
- DataFrame의 [ ] 연산자 내부에 칼럼명 입력 시 Series 형태로 특정 칼럼 데이터 세트가 반환됨
<class 'pandas.core.series.Series'>
- pd.Series.value_counts():
- Series 객체 반환
- 지정된 칼럼의 데이터값 건수를 반환
- 많은 건수 순서로 정렬되어 값을 반환
● 판다스의 index 객체
- 모든 DataFrame 내의 데이터는 생성되는 순간 고유의 Index 값을 가지게 됨
- 단순히 순차 값과 같은 의미 없는 식별자만 할당하는 것이 아닌 고유성이 보장된다면 의미 있는 데이터값고 할당 가능
- 문자열도 인덱스로 지정 가능
※ 모든 인덱스는 고유성이 보장되어야 함
2. DataFrame과 리스트, 딕셔너리, 넘파이 ndarray 상호 변환
- DataFrame은 다양한 데이터로부터 생성될 수 있고, 다양한 데이터로 변환할 수 있음
● 넘파이 ndarray, 리스트, 딕셔너리를 DataFrame으로
- DataFrame은 리스트/ 넘파이 ndarray와 다르게 칼럼명을 가지고 있음
- DataFrame으로 변환 시 칼럼명을 지정해 줌(지정 x -> 자동으로 칼럼명 할당)
pd.DataFrame(data, columns = )
: pandas DataFrame을 생성하는 함수- DataFrame은 기본적으로 행과 열을 가지는 2차원 데이터
- 2차원 이하의 데이터들만 DataFrame으로 변환될 수 있음
- 1차원 형태의 데이터를 기반으로 DataFrame 생성 시 칼럼명은 1개가 필요
- 2차원인 경우 열의 개수만큼
- 딕셔너리의 경우 key는 칼럼명으로, 값(value)는 키에 해당하는 칼럼 데이터로 변환됨
● DataFrame을 넘파이 ndarray, 리스트, 딕셔너리로 변환
pd.DataFrame.values
: pd.DataFrame -> np.ndarray- pd.DataFrame.values.
toist()
`: pd.DataFrame -> list pd.DataFrame.to_dict()
- pd.DataFrame -> 딕셔너리
- 인자로 ‘list’ 입력 시 딕셔너리의 값이 리스트형으로 반환됨
3. DataFrame의 컬럼 데이터 셋 생성과 수정
[ ]
연산자 이용- 새로운 칼럼 생성 시 DataFrame[] 내에 새로운 칼럼명을 입력하고 값을 할당해주기만 하면 됨
- 기존 칼럼 Series의 데이터를 이용해 새로운 칼럼 Series를 생성할 수 있음
- 기존 칼럼 값을 변경하려면 업데이트를 원하는 칼럼 Series를 DataFrame[] 내에 칼럼명으로 입력한 뒤 값을 할당해 주면 됨
4. DataFrame 데이터 삭제
pd.DataFrame.drop()
: DataFrame에서 데이터 삭제
DataFrame.drop(labels= None, axis = 0, index = None, columns = None, level = None, inplace = False, erros = 'raise')
- labels:
- drop을 희망하는 칼럼명을 지정
- 여러 개의 칼럼 삭제 희망 시 리스트 형태로 삭제하고자 하는 칼럼명을 입력하면 됨
-
axis: drop 수행 시 축을 지정(axis=0: 행, axis=1: 열)
- inplace = True
- 자신의 DataFrame의 데이터를 삭제
- 반환값: None -> 다시 자신의 DataFrame 객체에 할당하면 안 됨
5. Index 객체
- DataFrame, Series의 레코드를 고유하게 식별하는 객체
index
속성을 통해 Index 객체만 추출 가능- 반한된 Index 객체의 실제 값은 넘파이 1차원 ndarray로 확인 가능
- Index.
values
로 확인
- Index.
- 식별성 데이터를 1차원 array로 가지고 있음
- ndarray와 유사하게 단일 값 반환 및 슬라이싱 가능
- 한 번 만들어진 DataFrame 및 Series의 Index 객체는 함부로 변경할 수 없음
- Series 객체에 연산 함수 적용 시 Index는 연산에서 제외됨
- Index는 오직 식별용으로만 사용됨
reset_index()
- DataFrame 또는 Series에 새롭게 인덱스를 연속 숫자 형으로 할당
- 기존 인덱스는 index라는 새로운 칼럼으로 추가됨
- Series에 적용 시 DataFrame이 반환됨
- 기존 index가 칼럼으로 추가되어 칼럼 수가 2개가 되므로
drop = True
: 기존 인덱스가 새로운 칼럼으로 추가되지 않고 삭제(drop)됨- Series의 경우 그대로 Series로 유지됨
- DataFrame 또는 Series에 새롭게 인덱스를 연속 숫자 형으로 할당
6.데이터 셀렉션 및 필터링
● DataFrame의 [ ] 연산자
- 칼럼 명 문자(칼럼 명의 리스트 객체) or 인덱스로 변환 가능한 표현식이 들어갈 수 있음
- 인덱스(숫자) 사용 시 에러 발생(KeyError)
- 슬라이싱의 경우 판다스의 인덱스 형태로 변환 가능 -> 에러x
- but 사용을 권장하진 않음
- 불린 인덱싱 표현도 가능함
● 명칭 기반 인덱싱과 위치 기반 인덱싱의 구분
- 명칭(label) 기반 인덱싱
- 칼럼의 명칭을 기반으로 위치를 지정하는 방식
- ‘칼럼 명’과 같이 명칭으로 열 위치를 지정하는 방식
- 위치(Position) 기반 인덱싱
- 0을 출발점으로 하는 가로축, 세로축 좌표 기반의 행과 열 위치를 기반으로 데이터 지정
- 행, 열의 위치 좌표에만 의존
- 결과적으로 DataFrame의 인덱스 값은 명칭 기반 인덱싱이라고 간주해야 함
● DataFrame의 iloc[] 연산자
- 위치 기반 인덱싱
- 행과 열 값으로 integer 또는 integer형의 slicing, 팬시 리스트 값을 입력해 줘야 함
- 슬라이싱과 팬시 인덱싱 제공
- but 명확한 위치 기반 인덱싱이 사용되어야 함 -> 불린 인덱싱은 제공 x
● DataFrame의 loc[] 연산자
- 명칭 기반 인덱싱
- 행 위치에는 DataFrame의 index값 입력
- 열 위치에는 칼럼명 입력
- ⭐ loc에 슬라이싱을 적용하는 경우 종료 값 또한 포함됨
- 명칭 기반 인덱싱의 특성
● 불린 인덱싱
- iloc[]에서는 지원 x
- [] 내에 불린 인덱싱 적용 시 반환되는 객체는 DataFrame
- 원하는 칼럼 명만 별도로 추출할 수 있음
- ex>
titanic_df[titanic_df['Age'] > 60][['Name','Age']].head(3)
- loc[]를 이용하는 경우 칼럼 위치에 놓여야 함
titanic_df.loc[ titanic_df['Age'] > 60, ['Name','Age'] ].head(3)
- 여러 개의 복합 조건도 결합하여 적용 가능
- and 조건: &
-
or 조건: - Not 조건: ~
- 개별 조건을 변수에 할당하고 이들 변수를 결합하여 불린 인덱싱을 수행할 수도 있음
cond1 = titanic_df['Age'] > 60 cond2 = titanic_df['Pclass']==1 cond3 = titanic_df['Sex']=='female' titanic_df[ cond1 & cond2 & cond3]
7. 정렬, Aggregation 함수, GroupBy 적용
● DataFrame, Series의 정렬 - sort_values()
- sort_values(by, ascending, inplace)
- by:
- 정렬을 수행할 기준 컬럼
- 여러 컬럼을 지정하려는 경우 리스트 형식으로 입력하면 됨
- ascending = True: 오름차순 정렬(default: ascending = True)
- inplace = True: 호출한 DataFrame의 정렬 결과를 원본 DataFrame에 덮어씀(default: inplace = False)
- by:
●Aggregation 함수 적용
- min(), max(), sum(), count() 등
- DataFrame에서 바로 aggregation을 호출할 경우 모든 칼럼에 연산 적용
- 특정 칼럼에만 적용하려면 칼럼 추출 후 aggregation을 적용해야 함
● groupby() 적용
- by 파라미터로 지정된 칼럼으로 groupby
- DataGroupBy라는 또 다른 형태의 DataFrame을 반환
<class 'pandas.core.groupby.generic.DataFrameGroupBy'>
- DataFrame에 groupby()를 호출한 후 반환된 결과에 aggregation 함수를 호출하면 groupby() 대상 칼럼을 제외한 모든 칼럼에 해당 aggregation 함수를 적용
-
특정 칼럼만 aggregation 함수를 적용하려면 groupby()로 반환된 DataFrameGroupBy 객체에 해당 칼럼을 필터링한 뒤 aggregation 함수를 적용
ex>titanic_groupby = titanic_df.groupby('Pclass')[['PassengerId', 'Survived']].count() titanic_groupby
- 서로 다른 aggregation 함수를 적용할 시 여러 개의 aggregation 함수명을 DataFrameGroupBy 객체의 agg() 내에 인자로 입력해서 사용
-
여러 개의 칼럼이 서로 다른 aggregation 함수를 groupby에서 호출하려면 agg() 내에 딕셔너리 형태로 칼럼명과 함수를 입력
ex>agg_format={'Age':'max', 'SibSp':'sum', 'Fare':'mean'} titanic_df.groupby('Pclass').agg(agg_format)
8. 결손 데이터 처리하기
- 결손 데이터
- 칼럼에 값이 없는, 즉 NULL인 경우를 의미
- 넘파이의 NaN으로 표시
- 기본적인 머신러닝 알고리즘에서 처리되지 x
- 평균, 총합 등의 함수 연산 시 제외됨
pd.DataFrame.isna()
를 통해 NaN 여부 확인pd.DataFrame.fillna()
를 통해 NaN을 다른 값으로 대체
● isna()로 결손 데이터 여부 확인
- 모든 칼럼의 값이 NaN인지 아닌지를 True/False 값으로 알려줌
- isna() 결과에
sum()
함수를 추가해 결손 데이터의 개수를 구할 수 있음- True는 내부적으로 숫자 1로, False는 숫자 0으로 변환됨
● fillna( ) 로 Missing 데이터 대체하기
- 결손 데이터를 다른 값으로 대체
pd.DataFrame.fillna('대체값')
형태- fillna()를 이용해 반환 값을 다시 받거나
inplace = True
파라미터를 추가해야 실제 데이터 세트에 값이 변경됨
9. apply lambda 식으로 데이터 가공
- apply 함수에 lambda 식을 결합해 레코드별로 데이터를 가공할 수 있음
- lambda 식
- 함수의 선언과 함수 내의 처리를 한 줄의 식으로 쉽게 변환하는 식
lambda x: x**2
: 왼쪽은 입력 인자, 오른쪽은 입력 인자의 계산식- 여러 개의 값을 입력 인자로 사용 시 보통
map()
함수를 결합하여 사용 - if~else절 사용 시 if 식보다 반환 값을 먼저 기술해야 함
- 더 세분화된 분류가 필요한 경우 아예 별도의 함수를 만든 후 이를 호출
ex>
titanic_df['Age_cat'] = titanic_df['Age'].apply(lambda x : get_category(x)) # 사용자 지정 함수 titanic_df[['Age','Age_cat']].head()
📚 Reference
- 파이썬 머신러닝 완벽가이드_권철민 저, 개정2판(p.39 ~ 86)