[실무 테크닉 연습] - (2) 대리점 데이터 가공

Jungmin·2023년 2월 26일
0

데이터 분석

목록 보기
23/24
post-thumbnail

📙대리점의 매출 이력과 고객 정보 데이터를 이용해서 데이터 분석과 예측을 위해 중요한 '데이터 가공'을 연습해보자.

🤔시스템에 의해 관리되는 데이터가 아닌 경우, 종종 사람의 입력 실수나 누락 등으로 오류가 포함될 가능성이 있다. 이로인해 잘못된 결과를 도출하거나, 가공 처리부터 어려움을 겪는 경우가 있다.
실제 현장에서도 잘 정리된 데이터 보다는 소위 '지저분한' 데이터 형식을 만나게 될 가능성이 높으므로, 이런 데이터를 처리하는 경험을 쌓아보자.

✔ 전제조건

상품 A~Z까지 26개 상품을 취급하며, 매출 이력과 고객 정보 데이터는 담당직원이 직접 시스템에 입력한다. 집계기간 상품 단가 변동은 없고, 매출이력은 시스템에서 csv파일로 출력했다. 고객 정보는 주별로 집계하여 엑셀로 관리한다.

데이터개요
uriage.csv매출이력 (2019.01~2019.07)
kokyaku_daicho.xlsx대리점에서 관리하는 고객 정보

# 경고(warning) 비표시
import warnings
warnings.filterwarnings('ignore')

1. 데이터 읽어오기

import pandas as pd
uriage_data = pd.read_csv("uriage.csv")
uriage_data.head()
purchase_date item_name item_price customer_name
0 2019-06-13 18:02 상품A 100.0 김가온
1 2019-07-13 13:05 상 품 S NaN 김우찬
2 2019-05-11 19:42 상 품 a NaN 김유찬
3 2019-02-12 23:40 상품Z 2600.0 김재현
4 2019-04-22 3:09 상품a NaN 김강현
kokyaku_data = pd.read_excel("kokyaku_daicho.xlsx")
kokyaku_data.head()
고객이름 지역 등록일
0 김 현성 H시 2018-01-04 00:00:00
1 김 도윤 E시 42782
2 김 지한 A시 2018-01-07 00:00:00
3 김 하윤 F시 42872
4 김 시온 E시 43127

2. 데이터의 오류 확인

uriage_data["item_name"].head()
0      상품A
1    상 품 S
2    상 품 a
3      상품Z
4      상품a
Name: item_name, dtype: object

▶상품 명의 형식이 일관되지 않음을 볼 수 있다. 대소문자 / 공백 유무로 다른 데이터로 인식하기 때문에 정리가 필요해보임.

uriage_data["item_price"].head()
0     100.0
1       NaN
2       NaN
3    2600.0
4       NaN
Name: item_price, dtype: float64

▶결측치도 있음.
결측치를 처리하는 방법에 따라 결과도 많이 달라지기 때문에 전체 분포도 잘 살펴보자.

kokyaku_data["등록일"].head()
0    2018-01-04 00:00:00
1                  42782
2    2018-01-07 00:00:00
3                  42872
4                  43127
Name: 등록일, dtype: object

▶등록일 기준에 4xxxx은 무엇?

데이터에 입력 오류나 표기방법 차이가 부정합을 일으키면 '데이터의 정합성에 문제가 있다'라고 하는데, 위의 데이터가 좋은 사례이다.

3.데이터에 오류가 있는 상태로 집계해보기

⏺ 먼저 매출이력에서 상품별 월 매출 합계를 집계해보자.

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
item_name 상 품 n 상품 E 상품 M 상품 P 상품 S 상품 W 상품 X 상품W 상 품O 상 품Q ... 상품k 상품l 상품o 상품p 상품r 상품s 상품t 상품v 상품x 상품y
purchase_month
201901 1 0 0 0 0 0 0 0 0 0 ... 1 1 1 0 0 0 0 0 0 0
201902 0 0 0 0 0 0 1 0 0 0 ... 0 0 0 0 0 1 1 1 0 0
201903 0 1 1 1 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0
201904 0 0 0 0 0 0 0 1 0 1 ... 0 0 0 0 0 1 0 0 0 0
201905 0 0 0 0 1 0 0 0 0 0 ... 0 1 0 0 0 0 0 0 0 1
201906 0 0 0 0 0 1 0 0 0 0 ... 0 0 0 1 0 0 0 0 1 0
201907 0 0 0 0 0 0 0 0 1 0 ... 0 0 1 0 2 0 0 0 0 0

7 rows × 99 columns

▶컬럼을 보면 상품S와 상품s를 다른 품목으로 인식한 것을 볼 수 있다. 총 상품은 26개인데 위의 표를 보면 99개의 컬럼, 즉 상품을 99가지로 인식하고 있다.

가로축에 item_price를 설정해서 집계해보자.

res = uriage_data.pivot_table(index="purchase_month", columns="item_name", values="item_price", aggfunc="sum", fill_value=0)
res
item_name 상 품 n 상품 E 상품 M 상품 P 상품 S 상품 W 상품 X 상품W 상 품O 상 품Q ... 상품k 상품l 상품o 상품p 상품r 상품s 상품t 상품v 상품x 상품y
purchase_month
201901 1400 0 0 0 0 0 0 0 0 0 ... 1100 1200 1500 0 0 0 0 0 0 0
201902 0 0 0 0 0 0 2400 0 0 0 ... 0 0 0 0 0 1900 2000 2200 0 0
201903 0 500 1300 1600 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0
201904 0 0 0 0 0 0 0 2300 0 1700 ... 0 0 0 0 0 1900 0 0 0 0
201905 0 0 0 0 1900 0 0 0 0 0 ... 0 1200 0 0 0 0 0 0 0 2500
201906 0 0 0 0 0 2300 0 0 0 0 ... 0 0 0 1600 0 0 0 0 2400 0
201907 0 0 0 0 0 0 0 0 0 0 ... 0 0 1500 0 1800 0 0 0 0 0

7 rows × 99 columns

4. 상품명의 오류를 수정하자

⏺위의 상태로 분석을 하면 전혀 의미없는 결과가 나오기 때문에 가공단계가 전처리로 얼마나 중요한지 확인했다. 오류를 이제 수정해보자.

#상품명의 수 확인
len(uriage_data["item_name"].unique())
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)
purchase_date item_name item_price customer_name purchase_month
0 2019-06-13 18:02:00 상품A 100.0 김가온 201906
1748 2019-05-19 20:22:00 상품A 100.0 김시훈 201905
223 2019-06-25 08:13:00 상품A 100.0 김유진 201906
1742 2019-06-13 16:03:00 상품A 100.0 김건희 201906
1738 2019-02-10 00:28:00 상품A 100.0 김하랑 201902
... ... ... ... ... ...
2880 2019-04-22 00:36:00 상품Y NaN 김동욱 201904
2881 2019-04-30 14:21:00 상품Y NaN 김하준 201904
1525 2019-01-24 10:27:00 상품Y 2500.0 김범준 201901
1361 2019-05-28 13:45:00 상품Y 2500.0 김수현 201905
3 2019-02-12 23:40:00 상품Z 2600.0 김재현 201902

2999 rows × 5 columns

print(len(uriage_data["item_name"].unique()))
print(uriage_data["item_name"].unique())
26
['상품A' '상품S' '상품Z' '상품V' '상품O' '상품U' '상품L' '상품C' '상품I' '상품R' '상품X' '상품G'
 '상품P' '상품Q' '상품Y' '상품N' '상품W' '상품E' '상품K' '상품B' '상품F' '상품D' '상품M' '상품H'
 '상품T' '상품J']

▶상품명 처리!

5. 금액의 결측치를 수정해보자.

uriage_data.isnull().any()
purchase_date     False
item_name         False
item_price         True
customer_name     False
purchase_month    False
dtype: bool

▶item_price 컬럼에 결측치가 있다.

✔해당 데이터의 경우, 집계 기간에 상품 단가 변동이 없었기 때문에, 결측치는 같은 상품 단가를 이용해서 수정할 수 있다.

#어떤 행에 결측치 있는지 저장
flg_is_null = uriage_data["item_price"].isnull()
flg_is_null
0       False
1        True
2        True
3       False
4        True
        ...  
2994    False
2995    False
2996     True
2997     True
2998    False
Name: item_price, Length: 2999, dtype: bool
#결측치 있는 상품명 리스트 
list(uriage_data.loc[flg_is_null, "item_name"])[:5]
['상품S', '상품A', '상품A', '상품A', '상품A']
# unique()로 중복을 제거해서 불필요한 반복 방지 후 for문 돌리기
for trg in list(uriage_data.loc[flg_is_null, "item_name"].unique()):
    # 결측치가 있는 상품과 같은 상품을 찾고, 올바르게 입력된 행의 loc을 찾아 그 금액을 가져온다. 
    price = uriage_data.loc[(~flg_is_null) & (uriage_data["item_name"] == trg), "item_price"].max()
    # 가져온 금액으로 수정
    uriage_data["item_price"].loc[(flg_is_null) & (uriage_data["item_name"]==trg)] = price
uriage_data.head()
purchase_date item_name item_price customer_name purchase_month
0 2019-06-13 18:02:00 상품A 100.0 김가온 201906
1 2019-07-13 13:05:00 상품S 1900.0 김우찬 201907
2 2019-05-11 19:42:00 상품A 100.0 김유찬 201905
3 2019-02-12 23:40:00 상품Z 2600.0 김재현 201902
4 2019-04-22 03:09:00 상품A 100.0 김강현 201904

▶결측치 처리 후 검증

uriage_data.isnull().any()
purchase_date     False
item_name         False
item_price        False
customer_name     False
purchase_month    False
dtype: bool

▶각 상품 금액이 정상적으로 수정되었는지 확인해보자.

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)))
    #skipna는 NaN의 무시여부를 설정. False로 지정했기 떄문에 NaN이 존재하는 경우 최솟값이 NaN으로 표시된다. 
상품A의최고가:100.0의최저가:100.0
상품B의최고가:200.0의최저가:200.0
상품C의최고가:300.0의최저가:300.0
상품D의최고가:400.0의최저가:400.0
상품E의최고가:500.0의최저가:500.0
상품F의최고가:600.0의최저가:600.0
상품G의최고가:700.0의최저가:700.0
상품H의최고가:800.0의최저가:800.0
상품I의최고가:900.0의최저가:900.0
상품J의최고가:1000.0의최저가:1000.0
상품K의최고가:1100.0의최저가:1100.0
상품L의최고가:1200.0의최저가:1200.0
상품M의최고가:1300.0의최저가:1300.0
상품N의최고가:1400.0의최저가:1400.0
상품O의최고가:1500.0의최저가:1500.0
상품P의최고가:1600.0의최저가:1600.0
상품Q의최고가:1700.0의최저가:1700.0
상품R의최고가:1800.0의최저가:1800.0
상품S의최고가:1900.0의최저가:1900.0
상품T의최고가:2000.0의최저가:2000.0
상품U의최고가:2100.0의최저가:2100.0
상품V의최고가:2200.0의최저가:2200.0
상품W의최고가:2300.0의최저가:2300.0
상품X의최고가:2400.0의최저가:2400.0
상품Y의최고가:2500.0의최저가:2500.0
상품Z의최고가:2600.0의최저가:2600.0

6. 고객이름의 오류를 수정하자

#고객 정보의 고객 이름
kokyaku_data["고객이름"].head()
0    김 현성
1    김 도윤
2    김 지한
3    김 하윤
4    김 시온
Name: 고객이름, dtype: object
# 매출 이력의 고객 이름
uriage_data["customer_name"].head()
0    김가온
1    김우찬
2    김유찬
3    김재현
4    김강현
Name: customer_name, dtype: object
# 공백이 보이므로, 일단 제거해서 통일시킨다. 
kokyaku_data["고객이름"] = kokyaku_data["고객이름"].str.replace(" ", "")
kokyaku_data["고객이름"] = kokyaku_data["고객이름"].str.replace(" ", "")
kokyaku_data["고객이름"].head()
0    김현성
1    김도윤
2    김지한
3    김하윤
4    김시온
Name: 고객이름, dtype: object

7. 날짜오류를 수정하자

⏺고객 대장의 등록일 오류를 수정해보자. 4xxxx처럼 날짜 형식이 아닌 경우가 무엇이었는지 보기.

#숫자로 읽히는 데이터 확인
#고객 정보의 등록일이 숫자인지 아닌지를 str.isdigit()로 판정하고, 숫자로 된 장소를 flg_is_serial에 저장해서 갯수 확인
flg_is_serial = kokyaku_data["등록일"].astype("str").str.isdigit()
flg_is_serial.sum()
22
kokyaku_data["등록일"]
0      2018-01-04 00:00:00
1                    42782
2      2018-01-07 00:00:00
3                    42872
4                    43127
              ...         
195    2017-06-20 00:00:00
196    2018-06-20 00:00:00
197    2017-04-29 00:00:00
198    2019-04-19 00:00:00
199    2019-04-23 00:00:00
Name: 등록일, Length: 200, dtype: object

pd.to_timedelta() 함수로 숫자를 날짜로 변환한다. loc()을 이용해서 데이터 추출하고, 날짜로 변경한다.

fromSerial = pd.to_timedelta(kokyaku_data.loc[flg_is_serial, "등록일"].astype("float"), unit="D") + pd.to_datetime("1900/01/01")
fromSerial
1     2017-02-18
3     2017-05-19
4     2018-01-29
21    2017-07-06
27    2017-06-17
47    2017-01-08
49    2017-07-15
53    2017-04-10
76    2018-03-31
80    2018-01-12
99    2017-06-01
114   2018-06-05
118   2018-01-31
122   2018-04-18
139   2017-05-27
143   2017-03-26
155   2017-01-21
172   2018-03-24
179   2017-01-10
183   2017-07-26
186   2018-07-15
192   2018-06-10
Name: 등록일, dtype: datetime64[ns]
# 날짜로 변환된 데이터도 서식을 통일한다.
fromString = pd.to_datetime(kokyaku_data.loc[~flg_is_serial, "등록일"])
fromString
0     2018-01-04
2     2018-01-07
5     2017-06-20
6     2018-06-11
7     2017-05-19
         ...    
195   2017-06-20
196   2018-06-20
197   2017-04-29
198   2019-04-19
199   2019-04-23
Name: 등록일, Length: 178, dtype: datetime64[ns]
kokyaku_data["등록일"] = pd.concat([fromSerial, fromString])
kokyaku_data
고객이름 지역 등록일
0 김현성 H시 2018-01-04
1 김도윤 E시 2017-02-18
2 김지한 A시 2018-01-07
3 김하윤 F시 2017-05-19
4 김시온 E시 2018-01-29
... ... ... ...
195 김재희 G시 2017-06-20
196 김도영 E시 2018-06-20
197 김이안 F시 2017-04-29
198 김시현 H시 2019-04-19
199 김서우 D시 2019-04-23

200 rows × 3 columns

▶등록일로부터 등록월을 추출해서 집계해보기.

kokyaku_data["등록연월"] = kokyaku_data["등록일"].dt.strftime("%Y%m")
rslt = kokyaku_data.groupby("등록연월").count()["고객이름"]
print(rslt)
print(len(kokyaku_data))
등록연월
201701    15
201702    11
201703    14
201704    15
201705    13
201706    14
201707    17
201801    13
201802    15
201803    17
201804     5
201805    19
201806    13
201807    17
201904     2
Name: 고객이름, dtype: int64
200
# 등록일 컬럼에 숫자 데이터가 남아있는지 확인
flg_is_serial = kokyaku_data["등록일"].astype("str").str.isdigit()
flg_is_serial.sum()
0

8. 고객이름을 키로 두개의 데이터를 결합(조인)

# how='left'로, uriage_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)
join_data
purchase_date item_name item_price purchase_month 고객이름 지역 등록일 등록연월
0 2019-06-13 18:02:00 상품A 100.0 201906 김가온 C시 2017-01-26 201701
1 2019-07-13 13:05:00 상품S 1900.0 201907 김우찬 C시 2018-04-07 201804
2 2019-05-11 19:42:00 상품A 100.0 201905 김유찬 A시 2018-06-19 201806
3 2019-02-12 23:40:00 상품Z 2600.0 201902 김재현 D시 2018-07-22 201807
4 2019-04-22 03:09:00 상품A 100.0 201904 김강현 D시 2017-06-07 201706
... ... ... ... ... ... ... ... ...
2994 2019-02-15 02:56:00 상품Y 2500.0 201902 김정민 B시 2017-07-01 201707
2995 2019-06-22 04:03:00 상품M 1300.0 201906 김재원 E시 2018-03-31 201803
2996 2019-03-29 11:14:00 상품Q 1700.0 201903 김지율 B시 2017-03-15 201703
2997 2019-07-14 12:56:00 상품H 800.0 201907 김승주 E시 2018-07-15 201807
2998 2019-07-21 00:31:00 상품D 400.0 201907 정준기 B시 2017-02-05 201702

2999 rows × 8 columns

9. 정제한 데이터를 덤프

⏺컬럼을 약간 정리한 후에 가공한 데이터를 저장해두자

dump_data = join_data[["purchase_date", "purchase_month", "item_name", "item_price", "고객이름", "지역", "등록일"]]
dump_data
purchase_date purchase_month item_name item_price 고객이름 지역 등록일
0 2019-06-13 18:02:00 201906 상품A 100.0 김가온 C시 2017-01-26
1 2019-07-13 13:05:00 201907 상품S 1900.0 김우찬 C시 2018-04-07
2 2019-05-11 19:42:00 201905 상품A 100.0 김유찬 A시 2018-06-19
3 2019-02-12 23:40:00 201902 상품Z 2600.0 김재현 D시 2018-07-22
4 2019-04-22 03:09:00 201904 상품A 100.0 김강현 D시 2017-06-07
... ... ... ... ... ... ... ...
2994 2019-02-15 02:56:00 201902 상품Y 2500.0 김정민 B시 2017-07-01
2995 2019-06-22 04:03:00 201906 상품M 1300.0 김재원 E시 2018-03-31
2996 2019-03-29 11:14:00 201903 상품Q 1700.0 김지율 B시 2017-03-15
2997 2019-07-14 12:56:00 201907 상품H 800.0 김승주 E시 2018-07-15
2998 2019-07-21 00:31:00 201907 상품D 400.0 정준기 B시 2017-02-05

2999 rows × 7 columns

dump_data.to_csv("dump_data.csv", index=False)

10. 데이터를 집계하자

import_data = pd.read_csv("dump_data.csv")
import_data
purchase_date purchase_month item_name item_price 고객이름 지역 등록일
0 2019-06-13 18:02:00 201906 상품A 100.0 김가온 C시 2017-01-26
1 2019-07-13 13:05:00 201907 상품S 1900.0 김우찬 C시 2018-04-07
2 2019-05-11 19:42:00 201905 상품A 100.0 김유찬 A시 2018-06-19
3 2019-02-12 23:40:00 201902 상품Z 2600.0 김재현 D시 2018-07-22
4 2019-04-22 03:09:00 201904 상품A 100.0 김강현 D시 2017-06-07
... ... ... ... ... ... ... ...
2994 2019-02-15 02:56:00 201902 상품Y 2500.0 김정민 B시 2017-07-01
2995 2019-06-22 04:03:00 201906 상품M 1300.0 김재원 E시 2018-03-31
2996 2019-03-29 11:14:00 201903 상품Q 1700.0 김지율 B시 2017-03-15
2997 2019-07-14 12:56:00 201907 상품H 800.0 김승주 E시 2018-07-15
2998 2019-07-21 00:31:00 201907 상품D 400.0 정준기 B시 2017-02-05

2999 rows × 7 columns

#상품별 집계
byItem = import_data.pivot_table(index="purchase_month", columns="item_name", aggfunc="size", fill_value=0)
byItem
item_name 상품A 상품B 상품C 상품D 상품E 상품F 상품G 상품H 상품I 상품J ... 상품Q 상품R 상품S 상품T 상품U 상품V 상품W 상품X 상품Y 상품Z
purchase_month
201901 18 13 19 17 18 15 11 16 18 17 ... 17 21 20 17 7 22 13 14 10 0
201902 19 14 26 21 16 14 14 17 12 14 ... 22 22 22 23 19 22 24 16 11 1
201903 17 21 20 17 9 27 14 18 12 16 ... 23 16 20 12 23 18 16 21 16 0
201904 17 19 24 20 18 17 14 11 18 13 ... 20 20 16 16 11 15 14 16 20 0
201905 24 14 16 14 19 18 23 15 16 11 ... 13 22 18 16 16 9 21 16 20 0
201906 24 12 11 19 13 18 15 13 19 22 ... 15 16 21 12 18 20 17 15 13 0
201907 20 20 17 17 12 17 19 19 19 23 ... 15 19 23 21 13 28 16 18 12 0

7 rows × 26 columns

# 구입 연월, 매출 금액 집계
byPrice = import_data.pivot_table(index="purchase_month", columns="item_name", values="item_price", aggfunc="sum", fill_value=0)
byPrice
item_name 상품A 상품B 상품C 상품D 상품E 상품F 상품G 상품H 상품I 상품J ... 상품Q 상품R 상품S 상품T 상품U 상품V 상품W 상품X 상품Y 상품Z
purchase_month
201901 1800 2600 5700 6800 9000 9000 7700 12800 16200 17000 ... 28900 37800 38000 34000 14700 48400 29900 33600 25000 0
201902 1900 2800 7800 8400 8000 8400 9800 13600 10800 14000 ... 37400 39600 41800 46000 39900 48400 55200 38400 27500 2600
201903 1700 4200 6000 6800 4500 16200 9800 14400 10800 16000 ... 39100 28800 38000 24000 48300 39600 36800 50400 40000 0
201904 1700 3800 7200 8000 9000 10200 9800 8800 16200 13000 ... 34000 36000 30400 32000 23100 33000 32200 38400 50000 0
201905 2400 2800 4800 5600 9500 10800 16100 12000 14400 11000 ... 22100 39600 34200 32000 33600 19800 48300 38400 50000 0
201906 2400 2400 3300 7600 6500 10800 10500 10400 17100 22000 ... 25500 28800 39900 24000 37800 44000 39100 36000 32500 0
201907 2000 4000 5100 6800 6000 10200 13300 15200 17100 23000 ... 25500 34200 43700 42000 27300 61600 36800 43200 30000 0

7 rows × 26 columns

# 구입 연월, 고객별 구입 수 집계 결과
byCustomer = import_data.pivot_table(index="purchase_month", columns="고객이름", aggfunc="size", fill_value=0)
byCustomer
고객이름 김가온 김강민 김강현 김건우 김건희 김경민 김규민 김규현 김다온 김대현 ... 김현수 김현승 김현우 김현준 김현진 김호준 정도형 정영훈 정우석 정준기
purchase_month
201901 1 2 1 2 5 3 1 1 1 5 ... 3 2 4 2 1 1 4 4 4 3
201902 3 1 4 3 3 5 2 3 1 5 ... 5 3 7 0 0 1 2 0 2 2
201903 4 0 3 1 1 2 2 1 1 5 ... 3 2 1 2 1 2 1 2 3 4
201904 1 0 3 0 2 1 2 6 2 4 ... 0 4 3 1 1 2 2 4 3 1
201905 0 0 2 2 1 4 6 3 3 1 ... 2 2 1 4 3 0 0 0 1 2
201906 5 0 3 0 2 1 6 1 1 1 ... 2 4 1 0 4 2 2 0 0 2
201907 3 1 3 2 2 1 4 1 4 3 ... 2 1 0 4 0 2 6 1 2 3

7 rows × 199 columns

# 구입 연월, 지역별 판매 수 집계
byRegion = import_data.pivot_table(index="purchase_month", columns="지역", aggfunc="size", fill_value=0)
byRegion
지역 A시 B시 C시 D시 E시 F시 G시 H시
purchase_month
201901 59 55 72 34 49 57 49 42
201902 71 46 65 48 61 52 43 63
201903 64 52 57 43 52 59 51 59
201904 64 48 54 45 48 58 40 52
201905 57 52 68 48 59 65 35 43
201906 53 47 61 30 51 51 58 58
201907 76 53 61 42 54 64 47 54

▶import_data는 구매이력이 있는 uriage_data를 기준으로 왼쪽 조인된 결과이기 때문에,
기간 동안 구매이력이 없는 사람을 확인하려면 고객 대장을 기준으로 오른쪽 조인으로 다시 확인해야 된다.

# 집계 기간에 구매이력이 없는 사람
away_data = pd.merge(uriage_data, kokyaku_data, left_on="customer_name", right_on="고객이름", how="right") #고객 대장을 기준으로 합치기
away_data[away_data["purchase_date"].isnull()][["고객이름", "등록일"]]
고객이름 등록일
2999 김서우 2019-04-23
profile
데이터분석 스터디노트🧐✍️

0개의 댓글