3. 데이터 정제하기
1) 불필요한 데이터 삭제하기
1-1) 열 삭제하기
(1) 불리언 배열
(2) drop() 메서드
(3) dropna() 메서드
1-2) 행 삭제하기
(1) 불리언 배열
(2) drop() 메서드
(3) 중복된 행 찾기, duplicated() 메서드
(4) 그룹별로 모으기, groupby() 메서드
(5) 원본 데이터 업데이트하기
(6) 일괄 처리 함수 만들기
1-1) 열 삭제하기
(1) 불리언 배열
- 데이터프레임에 저장된 열 출력
- 열 속성은 [Index 클래스] 객체로 리스트처럼 숫자 인덱스로 참조할 수 있음
print(ns_df.columns)
print(ns_df.columns[0])
Index(['번호', '도서명', '저자', '출판사', '발행년도', 'ISBN', '세트 ISBN', '부가기호', '권', '주제분류번호', '도서권수', '대출건수', '등록일자', 'Unnamed: 13'], dtype='object')
번호
- 모든 원소를 하나씩 비교하여 True or False로 이루어진 불리언 배열로 반환함
ns_df.columns != 'Unnamed: 13'
array([ True, True, True, True, True, True, True, True, True, True, True, True, True, False])
- 'Unnamed: 13' 열이 아닌 것은 True가 되고, True인 열만 출력됨
selected_columns = ns_df.columns != 'Unnamed: 13'
ns_book = ns_df.loc[:, selected_columns]
ns_book.head()
(2) drop() 메서드
- 첫 번째 매개변수에 삭제하려는 열 이름을 지정하고 axis 매개변수=1로 지정 (기본값은 0이며, 행을 의미)
- '부가기호'와 'Unnamed: 13' 열이 삭제됨
- [inplace 매개변수]를 True로 지정하면 새로운 변수 지정 없이 바로 적용 가능
ns_book = ns_df.drop(['부가기호', 'Unnamed: 13'], axis=1)
ns_book.head()
ns_book.drop(['부가기호', 'Unnamed: 13'], axis=1, inplace=True)
ns_book.head()
(3) dropna() 메서드
- 판다스는 비어있는 값을 NaN으로 표시함
- NaN이 하나 이상 포함된 행 or 열을 삭제함
ns_book = ns_df.dropna(axis=1)
ns_book.head()
ns_book.dropna(axis=1, inplace=True)
ns_book.head()
- [how 매개변수]를 'all'로 지정하면, 모든 값이 NaN인 열을 삭제함
ns_book = ns_df.dropna(axis=1, how='all')
ns_book.head()
1-2) 행 삭제하기
(1) 불리언 배열
- 불리언 배열로 원하는 행을 True로 만들어 사용함
- 출판사가 '한빛미디어'인 행만 출력함
ns_book2 = ns_df[ns_df['출판사'] == '한빛미디어']
ns_book2.head()
(2) drop() 메서드
- 인덱스 0~1까지 2개의 행을 삭제함
ns_book2 = ns_book.drop([0,1])
ns_book2.head()
(3) 중복된 행 찾기, duplicated() 메서드
- 중복된 행은 True로 표시됨 (즉, 두 번째 행)
- sum() 함수는 True를 1로 인식하기 때문에, 중복된 행의 개수를 셀 수 있음
- 모든 열 기준은 번호가 고유한 값을 갖기에 중복된 행이 나올 수 없고, [subset 매개변수]로 특정 열 기준의 중복 행을 확인함
sum(ns_book.duplicated())
sum(ns_book.duplicated(subset=['도서명', '저자', 'ISBN']))
0
22096
- [keep 매개변수]를 False로 지정하여 중복된 모든 행을 True로 표시하여 출력함
dup_rows = ns_book.duplicated(subset=['도서명', '저자', 'ISBN'], keep=False)
ns_book3 = ns_book[dup_rows]
ns_book3.head()
(4) 그룹별로 모으기, groupby() 메서드
- 그룹별로 합칠 때 groupby()를 사용하며, [by 매개변수]에는 행을 합칠 때 기준이 되는 열을 지정함
- '도서명', '저자', 'ISBN'이 동일한 행을 합치고, [dropna 매개변수]를 False로 지정하여 NaN이 있는 행도 포함하여 대출권수를 더해서 출력함
count_df = ns_book[['도서명', '저자', 'ISBN', '대출건수']]
loan_count = count_df.groupby(by=['도서명', '저자', 'ISBN'], dropna=False).sum()
loan_count.head()
(5) 원본 데이터 업데이트하기
① 중복 없는 고유한 행만 선택하기
- duplicated()로 중복 행 True 표시, 고유한 행 선택을 위해 [~ 연산자]로 배열을 반전시킨 후, [copy()]로 고유한 행 선택
dup_rows = ns_book.duplicated(subset=['도서명', '저자', 'ISBN']) # 중복된 행을 True로 표시
unique_rows = ~dup_rows # 고유한 행을 True로 반전시킴
ns_book3 = ns_book[unique_rows].copy() # 고유한 행만 선택함
sum(ns_book3.duplicated(subset=['도서명', '저자', 'ISBN'])) # 중복된 행 개수 확인
0
② 원본 데이터프레임 인덱스 설정하기
- [set_index()]로 지정한 열을 인덱스로 설정하며, [inplace 매개변수]를 True로 지정하여 기존에 수정
ns_book3.set_index(['도서명', '저자', 'ISBN'], inplace=True)
ns_book3.head()
③ 업데이트 하기, update() 메서드
- update()로 원본 데이터프레임 값 업데이트 (대출건수 합계)
- [reset_index()]로 인덱스 열 해제
- [] 연산자로 열 이름 순서를 지정
ns_book3.update(loan_count)
ns_book4 = ns_book3.reset_index()
ns_book4 = ns_book4[ns_book.columns]
(6) 일괄 처리 함수 만들기
def data_cleaning(filename):
ns_df = pd.read_csv(filename, low_memory=False)
ns_book = ns_df.dropna(axis=1, how='all')
count_df = ns_book[['도서명','저자','ISBN','대출건수']]
loan_count = count_df.groupby(by=['도서명','저자','ISBN'], dropna=False).sum()
dup_rows = ns_book.duplicated(subset=['도서명','저자','ISBN'])
unique_rows = ~dup_rows
ns_book3 = ns_book[unique_rows].copy()
ns_book3.set_index(['도서명','저자','ISBN'], inplace=True)
ns_book3.update(loan_count)
ns_book4 = ns_book3.reset_index()
ns_book4 = ns_book4[ns_book.columns]
return ns_book4