책 정보 : https://book.naver.com/bookdb/book_detail.nhn?bid=16427881
파이썬 데이터 분석 실무 테크닉 100
《파이썬 데이터 분석 실무 테크닉 100》은 실제 비즈니스 현장에서 마주칠 수 있는 100개의 예제를 풀면서 현장 분위기를 몸에 익히고 현장에 맞게 기술을 응용하는 힘을 기를 수 있게 설계한 문
book.naver.com
[데이터 정보]
- uriage.csv : 매출 이력, 기간은 2019년 1월~2019년 7월
- kokyaku_daicho.xlsx : 대리점에서 관리하는 고객 정보
1. 데이터 읽어들이기
import pandas as pd
uriage_data = pd.read_csv("C:/data/2장/uriage.csv")
uriage_data.head()
- item_name이나 item_price에 결측치나 오류가 보임
- 이처럼 데이터에 나타나는 입력 오류나 표기 방법의 차이가 부정합을 일으킬 때 '데이터의 정합성에 문제가 있다'
kokyaku_data = pd.read_excel("C:/data/2장/kokyaku_daicho.xlsx")
kokyaku_data.head()
- 정합성을 갖추기 위해서는 데이터의 속성이나 의미를 이해해야 함
- 정합성 확보는 우선 데이터의 오류를 파악하는 것부터 시작
2. 데이터의 오류를 살펴보기
uriage_data["item_name"].head()
uriage_data["item_price"].head()
3. 데이터에 오류가 있는 상태로 집계하기
uriage_data["purchase_date"] = pd.to_datetime(uriage_data["purchase_date"]) # datetime형으로 변환
uriage_data["purchase_month"] = uriage_data["purchase_date"].dt.strftime("%Y%m") # 날짜를 연월 형태로 변환
# 세로축에 구입 연월, 가로축에 상품의 건수로 집계
res = uriage_data.pivot_table(index="purchase_month", columns="item_name", aggfunc="size", fill_value=0)
res
- '상품S'나 '상품s'처럼 원래 동일한 상품이 다른 상품으로 집계된 것을 확인할 수 있음 -> 원래 26개의 상품이 99개의 상품으로 늘어남
- 결측치(NaN) 포함 O -> size 함수 / 결측치(NaN) 포함 X -> count 함수
4. 상품명 오류 수정하기
현재 상태 파악하기
print(len(pd.unique(uriage_data.item_name))) # 상품명의 유니크 수(중복 제외) 확인
99 -> 원래 A~Z까지 26개의 상품이 99개로 늘어남
대문자로 변경 → 공백 제거 → 오름차순으로 정렬
uriage_data["item_name"] = uriage_data["item_name"].str.upper() # 상품명에 있는 소문자를 대문자로 변환
uriage_data["item_name"] = uriage_data["item_name"].str.replace(" ", "") # 공백 제거
uriage_data["item_name"] = uriage_data["item_name"].str.replace(" ", "") # 공백 제거
uriage_data.sort_values(by=["item_name"], ascending=True) # item_name 순으로 정렬
결과 검증 (상품명과 개수 가져오기)
print(pd.unique(uriage_data["item_name"]))
print(len(pd.unique(uriage_data.item_name)))
5. 금액의 결측치를 수정하기
우선, 데이터에 결측치가 있는지 확인하기
uriage_data.isnull().any(axis=0) # axis=0이면 행방향, axis=1이면 열방향
df.loc[조건, 조건과 일치하는 데이터 중에서 어떤 칼럼을 가져올지 결정] -> 조건에 일치하는 데이터를 추출
flg_is_null = uriage_data["item_price"].isnull() # item_price 중에 결측치가 있는 곳을 조사
uriage_data.loc[flg_is_null, "item_name"].unique()
- trg -> 위에서 구한 결측치가 있는 상품명 리스트들
- 같은 상품의 단가를 이용하여 결측치를 채우기
- price -> '결측치가 있는 상품'과 같은 상품이며 금액이 올바르게 입력된 행을 loc로 찾아 그 그액을 가져오기
- 결측치가 있는 데이터를 추출하고, 앞에서 가져온 금액 데이터 price를 결측치에 대입
for trg in list(uriage_data.loc[flg_is_null, "item_name"].unique()): # list()로 변수의 값을 리스트 형식으로 변환
# 결손치가 있는 상품과 같은 상품의 다른 데이터에서 금액을 가져올 수 있음
price = uriage_data.loc[(~flg_is_null) & (uriage_data["item_name"] == trg), "item_price"].max()
# 가져온 금액으로 데이터를 수정 -> 결측치가 있는 데이터를 추출하고, 앞에서 가져온 금액 데이터 price를 결측치에 대입
uriage_data["item_price"].loc[(flg_is_null) & (uriage_data["item_name"] == trg)] = price
uriage_data.head()
검증하기
uriage_data.isnull().any(axis=0)
각 상품의 금액이 정상적으로 수정됐는지 확인하기
for trg in list(uriage_data["item_name"].sort_values().uniqueque()):
print(trg + "의 최고가 : " + str(uriage_data.loc[uriage_data["item_name"] == trg]["item_price"].max()) +
"의 최저가 : " + str(uriage_data.loc[uriage_data["item_name"] == trg]["item_price"].min(skipna=False)))
- 모든 상품의 최대 금액과 최소 금액이 일치하는 것으로 봐서 성공적으로 금액을 수정했다는 것을 알 수 있음
- skipna=False에서 skipna는 NaN의 무시 여부를 설정
6. 고객 이름의 오류 수정하기
kokyaku_data["고객이름"].head() # 고객 정보의 고객 이름
uriage_data["customer_name"].head() # 매출 이력의 고객 이름
고객 정보의 고객 이름에서 공백을 제거하기
kokyaku_data["고객이름"] = kokyaku_data["고객이름"].str.replace(" ", "")
kokyaku_data["고객이름"] = kokyaku_data["고객이름"].str.replace(" ", "")
kokyaku_data["고객이름"].head() # 수정 후 고객 정보의 고객 이름
7. 날짜 오류 수정하기
kokyaku_data["등록일"].head()
- 여러 가지 서식의 날짜가 있는 것을 확인할 수 있음
- 동일한 포맷으로 통일해야 함
- 고객 정보의 등록일이 숫자인지 아닌지를 판정
- 등록일이 object지만 문자열(str)로 바꾼 후에 적용해야 함
- str.isdigit() : 문자열이 숫자인지 아닌지를 True, False로 리턴
flg_is_serial = kokyaku_data["등록일"].astype("str").str.isdigit()
# flg_is_serial
flg_is_serial.sum() # 숫자로만 된 등록일의 개수 -> 22
- 숫자로 등록된 부분을 수정
- to_timedelta() : 숫자를 날짜로 변환, unit="D" -> '~일'로 바꾸기
- loc()을 이용 -> flg_is_serial 조건으로 데이터를 추출하고 날짜로 변경
fromSerial = pd.to_timedelta(kokyaku_data.loc[flg_is_serial, "등록일"].astype("float"), unit="D") + pd.to_datetime("1900/01/01")
fromSerial # 숫자를 날짜로 변경
날짜로 변환된 데이터로 서식을 통일 (2018/01/4와 같이 슬래시로 구분된 서식을 하이픈으로 구분된 서식으로 통일)
fromString = pd.to_datetime(kokyaku_data.loc[~flg_is_serial, "등록일"])
fromString
숫자를 날짜로 수정한 데이터와 서식을 변경한 데이터를 결합해서 데이터를 갱신
kokyaku_data["등록일"] = pd.concat([fromSerial, fromString])
kokyaku_data
등록일로부터 등록월을 추출하여 집계하기
kokyaku_data["등록연월"] = kokyaku_data["등록일"].dt.strftime("%Y%m")
rslt = kokyaku_data.groupby("등록연월").count()["고객이름"]
print(rslt)
print(len(kokyaku_data))
등록된 칼럼에 숫자 데이터가 남아 있는지를 확인
flg_is_serial = kokyaku_data["등록일"].astype("str").str.isdigit()
flg_is_serial.sum() # 0 -> 모든 숫자 데이터가 날짜로 수정된 것을 확인
8. 고객 이름을 키로 두 개의 데이터를 결합(조인)하기
uriage_data를 기준으로 kokyaku_data를 결합
join_data = pd.merge(uriage_data, kokyaku_data, left_on="customer_name", right_on="고객이름", how="left")
join_data = join_data.drop("customer_name", axis=1) # 열(column)방향으로 해당 컬럼 제거 (중복이므로)
join_data
9. 정제한 데이터를 덤프하기
: 깨끗해진 데이터를 파일로 출력(더프)해두고, 분석할 때 출력한 파일을 다시 읽어 들이면 데이터 정제를 다시 할 필요가 없음
컬럼의 배치 조정 -> purchase_data와 purchase_month는 가까이 있는 편이 다루기 편함
dump_data = join_data[["purchase_date", "purchase_month", "item_name", "item_price", "고객이름", "지역", "등록일"]]
dump_data
- 수정한 dump_data를 to_csv()를 이용해서 파일로 출력하기
- 실행하면 같은 폴더에 dump_data.csv가 출력되는 것을 확인할 수 있음
dump_data.to_csv("dump_data.csv", index=False)
10. 데이터 집계하기
import_data = pd.read_csv("dump_data.csv")
import_data
purchase_month를 세로축으로 해서 상품별로 집계하기
byItem = import_data.pivot_table(index="purchase_month", columns="item_name", aggfunc="size", fill_value=0)
byItem
purchase_month를 세로축으로 지정하고 매출 금액 집계하기
byPrice = import_data.pivot_table(index="purchase_month", columns="item_name", values="item_price", aggfunc="sum", fill_value=0)
byPrice
purchase_month를 세로축으로 지정하고 고객 집계하기
byCustomer = import_data.pivot_table(index="purchase_month", columns="고객이름", aggfunc="size", fill_value=0)
byCustomer
purchase_month를 세로축으로 지정하고 지역 집계하기
byRegion = import_data.pivot_table(index="purchase_month", columns="지역", aggfunc="size", fill_value=0)
byRegion
집계 기간에 구매 이력이 없는 사용자 확인하기 -> 고객 대상을 기준으로 매출 이력을 오른쪽 조인해서 결합하기
away_data = pd.merge(uriage_data, kokyaku_data, left_on="customer_name", right_on="고객이름", how="right")
away_data[away_data["purchase_date"].isnull()][["고객이름", "등록일"]]
'Data analysis > 실습 & 프로젝트' 카테고리의 다른 글
[파이썬 데이터 분석 실무 테크닉 100] 1-1. 웹에서 주문 수를 분석하는 테크닉 10 (0) | 2022.05.28 |
---|---|
통계청 출생아수 데이터 분석하기 (0) | 2022.02.03 |
K-beauty 온라인 판매분석 (0) | 2022.01.30 |
건강검진 데이터로 가설검정하기 (0) | 2022.01.27 |
서울 종합병원 분포 확인하기 (0) | 2022.01.26 |