
저에게 몰아치던 할 일들이 끝나서 그런지
아무것도 하고 싶지 않은 상태가 되었습니다

그럼에도 할 일을 하려고 여러번 책과 함께 책상에 앉았지만...

족장님이 올리신 짤이 너무 공감되어 저장했어요
이전에 조금 지각해도 된다는 말에 힘을 받아... 조금 지각하고 (조금이 아닌 것 같지만요) 3주차 과제를 해내봅니다
3장은 불러온 데이터를 분석하기 쉽도록 정제하는 파트입니다.
pandas df에서 불필요한 정보를 삭제하거나 추가하거나 골라내거나... 하는 등의 코드를 주로 학습합니다
Ch.03 데이터 정제하기
03-1. 불필요한 데이터 삭제하기
1. 열 삭제하기
loc 매서드에 슬라이싱을 응용하는 방법
ns_book = ns_df.loc[:, '번호':'등록일자']
* [행, 열]
** loc 매서드에서 슬라이싱을 할 때는 마지막 요소도 포함
그러나 이 방법의 문제 -> 중간 열 하나만 제외하거나.. 이런 게 불가능함
무조건 연속되어있는 열들만 선택 가능
-> 불리언(boolean)배열을 사용하여 원하는 열만 선택
* 예전에는 불리언을 부울린이라고도 배운 듯 하다...
ns_df.columns는 열 이름의 배열이다. 이는 pandas의 index 클래스의 객체로 리스트와 비슷하게 기능한다.
다만 인덱스 클래스는 어떤 값과 비교할 때 그 값을 배열의 요소 하나하나와 모두 비교해준다!
selected_columns = ns_df.columns != 'Unnamed: 13'
#이렇게 인덱스 객체를 문자열과 비교하면, 요소 전체를 하나의 문자열과 비교해준다
*그 결과는 [True,False,False...] 처럼 불리언 배열로 나타난다
ns_book = ns_df.loc[:, selected_columns]
*loc 매서드에서 슬라이싱 조건으로 불리언 배열을 넣으면, True인 열만 살리게 된다
ns_book.head()
* Unnamed: 13 열 만 제외된 df가 생긴다
그런데... 열이 몇개인 줄 알고 하나하나 비교하고..불리언 배열을 만들고...귀찮지 않은가
그냥 딱 원하는 열 이름만 지정해서 뺄 수도 있다
- drop() 매서드
ns_book = ns_df.drop(['부가기호','Unnamed: 13'], axis=1)
*원하는 열의 이름을 적으면 된다. 여러개일때는 리스트 형식으로 적으면 된다
*axis는 기본적으로 0으로 설정되며 0은 행, 1은 열
ns_book.head()
만약 열을 삭제한 df를 새로운 이름으로 저장하는 것이 아닌, 초기 자료를 없애고 원래 이름의 df로 만들고 싶다면
ns_book.drop('주제분류번호', axis=1, inplace=True)
*inplace 설정을 True로 설정하면 그대로 같은 이름으로 저장됨
ns_book.head()
- dropna() 매서드
: 하나라도 NaN값이 있는 행이나 열을 삭제
ns_book = ns_df.dropna(axis=1)
ns_book = ns_df.dropna(axis=1, how='all')
*how=all이면 그 행이나 열의 모든 값이 NaN인걸 지우는 것
ns_book.head()
2. 행 삭제하기
똑같이 drop매서드로 행을 삭제할 수 있다.
행이기 때문에 축을 따로 지정할 필요도 없고, 행 이름은 인덱스로 가져가면 된다
ns_book2 = ns_book.drop([0,1])
*행 이름은 인덱스, 축 설정 없음
ns_book2.head()
행 선택에는 [] 연산자를 많이 사용하며 슬라이싱이나 불리언 배열을 이용한다
*loc매서드 사용가능
ns_book2 = ns_book[0:2]
* 이렇게 loc매서드가 아니라 그냥 슬라이싱이면 마지막 인덱스는 포함하지 않음
* 0과 1 행만 선택함
*불리언배열 만들기
selected_rows = ns_df['출판사'] == '한빛미디어'
ns_book2 = ns_book[selected_rows]
*불리언 배열을 그대로 넣으면 됨
ns_book2.head()
그런데 조건을 불리언 배열로 만들기는 귀찮은 일이다
비교코드를 만들어서 새로운 배열을 만들고, 그 배열을 다시 연산자 안에 넣는 거기 때문에...
그냥 비교코드를 바로 연산자 안에 넣어도 된다
ns_book2 = ns_book[ns_book['대출건수'] > 1000]
*[]연산자 안에 조건을 넣는 방식
3. 중복된 행 찾기
- duplicated() 매서드
중복된 행은 True, 중복되지 않은 행은 False로 불리언 배열을 반환
여기서 중복된 행은 처음 행을 제외한 나머지로, 같은 값을 가진 모든 행을 True로 표현하지 않음. 하나는 살려둠
모든 행의 값이 다 똑같아야 중복된 행으로 인정
*중복된 행이 존재하는지만 파악하고자 한다면
sum(ns_book.duplicated())
* sum 함수가 배열에서 True=1, False=0으로 합을 계산
만약 일부 열의 값이 중복되고 있는 걸 찾고 싶다면
sum(ns_book.duplicated(subset=['도서명','저자','ISBN']))
*subset 매개변수에 원하는 열의 이름을 넣으면 그 열을 기준으로 찾아줌
열을 여러개 넣으면, 그 모든 열의 값이 같은 행들을 찾음
중복된 모든 행을 뽑고 싶다면 ( 중복을 하나도 살려두지 않고 )
keep 매개변수를 변환하기
dup_rows = ns_book.duplicated(subset=['도서명','저자','ISBN'], keep=False)
*keep=false를 통해 중복된 열 중 첫번째는 False였던 걸 모두 True로 바꿈
ns_book3 = ns_book[dup_rows]
ns_book3.head(20)
중복된 열 그냥 지우고 싶다면
drop_duplicates()
똑같이 subset, keep 매개변수를 사용할 수 있다
4. 그룹별로 모으기
어떤 행이 동일한 값을 가지고 있다면, 그 열을 기준으로 행을 합칠 수 있다.
기준이 되는 열은 인덱스의 역할을 하게 된다.
- groupby()
*sum 함수를 따로 쓰는 방식
group_df = count_df.groupby(by=['도서명','저자','ISBN','권'], dropna=False)
loan_count = group_df.sum()
*sum 함수를 한번에 쓰는 방식
loan_count = count_df.groupby(by=['도서명','저자','ISBN','권'], dropna=False).sum()
loan_count.head()
*by 매개변수에는 기준으로 삼을 열의 이름을 적는다
** 만약 기준으로 삼을 열의 값이 NaN일 시 groupby 함수는 그 행을 삭제하는 특징이 있는데, dropna=False로 설정하면 삭제하지 않는다 (기본값은 Ture이다)
***groupby함수를 통해 행을 합친 후, 합쳐진 열이 아닌 다른 열에 원하는 결과를 얻기 위하여 함수를 넣는다 (ex. sum, average ...)
5. 원본 데이터를 업데이트 하기
dup_rows = ns_book.duplicated(subset=['도서명','저자','ISBN','권'])
unique_rows = ~dup_rows
* ~는 불리안 배열을 반전하는 연산자
ns_book3 = ns_book[unique_rows].copy()
* copy()매서드는 데이터프레임의 복사본을 만드는 것인데, 데이터프레임을 메모리공간에 저장하기 위해서,
또한 df를 제대로 업데이트 하기 위해서 copy를 하면 좋음
* 중복 행이 True고 중복되지 않은 행이 False기 때문에 이 불리안 배열을 가지고 새로운 df를 만들면 중복행만 출력된다.
따라서 중복되지 않은 행만 뽑으려면 불리안 배열을 반전시켜야 한다.
특정 열(들)을 인덱스로 만들고 싶다면
- set_index()
ns_book3.set_index(['도서명','저자','ISBN','권'], inplace=True)
*인덱스는 행 앞에 번호와 같은 기능이기에 설정한 열이 가장 앞으로 나온다
ns_book3.head()
- update() 매서드
인덱스를 맞춘 두 df가 있다면 update()매서드를 통해 두 df를 합치는 방식으로 업데이트가 가능하다.
같은 인덱스를 기준으로 다른 열이 있다면 한 df로 합친다.
ns_book3.update(loan_count)
*()안에 합치고자 하는 df의 이름을 넣는다
ns_book3.head()
*업데이트가 된 걸 확인하면 인덱스를 다시 해제한다.
ns_book4 = ns_book3.reset_index()
ns_book4.head()
*그러나 인덱스를 설정했다가 다시 해제하면 열의 순서가 바뀐다
*다시 원래대로 순서를 설정하려면 초기 df의 컬럼 배열을 []에 넣어 다시 원래대로 바꾼다
ns_book4 = ns_book4[ns_book.columns]
ns_book4.head()
*reset_indexs()는 인덱스를 초기화하는 매서드
-두 df가 같은지 확인하려면 equals()메서드를 활용하면 된다
03-2. 잘못된 데이터 수정하기
-기본과제

-추가과제

아무래도 정리를 해야 한다고 생각하니 더 하기 싫어지는 게 맞는 것 같아
정리는 천천히 복습 느낌으로 해나가야 할 것 같네요...
일단은 더 이상 늦지 않고 완독하는 걸 목표로 해보겠습니다
'혼공단' 카테고리의 다른 글
| [혼공분석] 6주차_Ch.6 복잡한 데이터 표현하기 (5) | 2025.08.18 |
|---|---|
| [혼공분석] 5주차_Ch.5 데이터 시각화하기 (4) | 2025.08.11 |
| [혼공분석] 4주차_Ch.4 데이터 요약하기 (4) | 2025.08.03 |
| [혼공분석] 2주차_Ch2. 데이터 수집 (7) | 2025.07.12 |
| [혼공분석]1주차_Ch1.천천히 정리해보자 (0) | 2025.07.04 |