9.18 Chapter 01
대리점 데이터를 가공하는 테크닉 10
데이터를 읽어 들이자
1
2
3
4
5
6
import pandas as pd
uriage_data = pd.read_csv("data/chap02/uriage.csv")
uriage_data.head() # 매출이력
kokyaku_data = pd.read_excel("data/chap02/kokyaku_daicho.xlsx")
kokyaku_data.head() # 고객정보
- 각 데이터를 읽어 들이고 처음 5행을 표시해서 데이터를 살펴봅니다.
- 데이터의 오류를 해소하고 정합성을 보장하는 것은 데이터 분석의 기초가 되는 중요한 부분으로, 정합성을 갖추기 위해서는 먼저 데이터의 속성이나 의미를 이해해야 합니다.
- 정합성 확보는 우선 데이터의 오류를 파악하는 것부터 시작합니다.
데이터의 오류를 살펴보자
- uriage_data의 item_name에서 알파벳 대/소문자가 섞여 있는 것을 확인할 수 있습니다.
- 또한 item_price에는 결측치 NaN을 확인할 수 있습니다.
데이터에 오류가 있는 상태로 집계해 보자
1
2
3
4
5
uriage_data["purchase_date"] = pd.to_datetime(uriage_data["purchase_date"])
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’ 처럼 원래 동일한 상품이 다른 상품으로 집계된 것을 확인할 수 있습니다.
데이터에 오류가 있는 상태로 집계 및 분석을 실시하면 전혀 의미 없는 결과가 나오기 때문에 데이터 가공이 분석의 전처리로 얼마나 중요한 지 확인할 수 있습니다.
상품명 오류를 수정하자
1
2
3
4
5
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)
- 위의 코드를 이용해서 상품명에 있는 소문자를 대문자로 변환합니다. 또한 공백을 제거합니다.
- 이러한 과정을 거쳤지만, 반드시 결과를 검증하는 것을 잊어서는 안 됩니다.
금액의 결측치를 수정하자
- 우선 데이터에 결측치가 있는 지 확인합니다.
1
uriage_data.isnull().any(axis=0)
- 이 후, 금액의 결손치를 수정해 줍니다.
1
2
3
4
5
6
fig_is_null = uriage_data["item_price"].isnull()
for trg in list(uriage_data.loc[fig_is_null, "item_name"].unique()):
price = uriage_data.loc[(~fig_is_null) & (uriage_data["item_name"] == trg),
"item_price"].max() # loc: 조건에 맞는 행과 열을 가져올 수 있음
uriage_data["item_price"].loc[(fig_is_null) & (uriage_data["item_name"] == trg)] = price
uriage_data.head()
- 다음으로 각 상품의 금액이 정상적으로 수정됐는지 확인합니다. 모든 상품의 최대 금액과 최소 금액이 일치하는 것으로 봐서 성공적으로 금액을 수정했다는 것을 알 수 있습니다.
1
2
3
4
for trg in list(uriage_data["item_name"].sort_values().unique()):
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)))
고객 이름의 오류를 수정하자
1
2
3
kokyaku_data["고객이름"].head()
uriage_data["customer_name"].head()
- 고객 정보와 매출 이력의 고객 이름을 비교해 보면, 고객 정보의 고객 이름에는 성과 이름 사이에 공백이 있지만, 매출 이력의 고객 이름에는 공백이 없습니다. 또한 공백이 한 칸이나 두 칸, 아니면 공백이 없는 등 서식이 혼재되어 있습니다.
1
2
3
kokyaku_data["고객이름"] = kokyaku_data["고객이름"].str.replace(" ", "")
kokyaku_data["고객이름"] = kokyaku_data["고객이름"].str.replace(" ", "")
kokyaku_data["고객이름"].head()
날짜 오류를 수정하자
1
2
fig_is_serial = kokyaku_data["등록일"].astype("str").str.isdigit()
fig_is_serial.sum()
- 위 확인 코드를 통해 숫자로 읽히는 데이터가 있음을 확인합니다.
1
2
3
4
5
6
7
8
9
10
fromSerial = pd.to_timedelta(kokyaku_data.loc[fig_is_serial, "등록일"]
.astype("float"), unit="D") + pd.to_datetime("1900/01/01")
# 숫자를 날짜로 변환
fromSerial
fromString = pd.to_datetime(kokyaku_data.loc[~fig_is_serial, "등록일"])
fromString
kokyaku_data["등록일"] = pd.concat([fromSerial, fromString])
kokyaku_data
- 숫자로 등록된 부분을 다음과 같이 수정해 줍니다.
- pd.to_timedelta() 함수는 숫자를 날짜로 변환합니다.
고객 이름을 키로 두 개의 데이터를 결합(조인)하자
1
2
3
4
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)
join_data
- 위의 과정을 통해 데이터를 가공함으로써 분석에 적합한 데이터의 형태가 되었습니다. 이런 데이터 가공을 데이터 정제라고도 합니다.
정제한 데이터를 덤프하자
- 깨끗해진 데이터를 파일로 출력(덤프)해두고, 분석할 때 출력한 파일을 다시 읽어 들이면 데이터 정제를 다시 할 필요가 없습니다.
1
2
3
4
5
dump_data = join_data[["purchase_date", "purchase_month", "item_name", "item_price",
"고객이름", "지역", "등록일"]]
dump_data
dump_data.to_csv("dump_data.csv", index=False)
데이터를 집계하자
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import_data = pd.read_csv("dump_data.csv")
import_data
byItem = import_data.pivot_table(index="purchase_month", columns="item_name",
aggfunc="size", fill_value=0) # 수량
byItem
byPrice = import_data.pivot_table(index="purchase_month", columns="item_name",
values="item_price", aggfunc="sum", fill_value=0)
byPrice
byCustomer = import_data.pivot_table(index="purchase_month", columns="고객이름",
aggfunc="size", fill_value=0)
byCustomer
byRegion = import_data.pivot_table(index="purchase_month", columns="지역",
aggfunc="size", fill_value=0)
byRegion
This post is licensed under CC BY 4.0 by the author.