본문 바로가기
데이터 시각화 및 애플리케이션 개발

[Matplotlib] 가상 온라인 쇼핑몰 데이터 다루기

by 바다의 공간 2024. 6. 20.

이번에는 54만개 이상 되는 많은 양의 데이터양의 CSV파일을 가져와서 다루어보려고 합니다.

이번 데이터 csv는 retail에 대한 값입니다. 

 

1.데이터 분석 

2. 시각화 표현

 

아래에있는 내용의 기본정보입니다.

  • InvoiceNo: 주문 번호
  • StockCode: 상품 코드
  • Description: 상품 설명
  • Quantity: 주문 수량
  • InvoiceDate: 주문 날짜
  • UnitPrice: 상품 가격
  • CustomerID: 고객 아이디
  • Country: 고객 거주지역(국가)

가장먼저 pandas로 임포트를 해주고

저는 구글드라이브에있는 파일연동을 시켜줍니다.

import pandas as pd

from google.colab import drive
drive.mount('/content/drive')

retail = pd.read_csv('경로복사')
retail

총 541909 rows * 8columns 입니다. 지난번 했던것보다 훨씬 많죠!


 

데이터 타입 확인하기

retail.info()

총 값은 541909가 있고  null값이 있는 데이터는 2번, 6번으로 확인할 수 있습니다.


각 컬럼의 null의 합계 갯수 확인

retail.isnull().sum()


각 컬럼의 null의 비율 확인

retail.isunll().mean()


비회원/탈퇴회원/휴면계정 제거

CustomerID가없으면 저장되지않음

retail = retail[pd.notnull(retail['CustomerID'])]
retail

내가 체득하기 위해 남겨놓는 코드해석

pd.notnull = pandas 라이브러리에서 제공하는 함수로 인자로 전달된 값이 null이 아닌지를 검사합니다

retail['CustomerID'] = retail 데이터프레임에서 CustomerID 열의 모든 값을 의미합니다.

pd.notnull(retail['CustomerID'] = CustomerID열에서 각 값이 null인지 확인하고 아닌값은 true, null인값은 false로 반환됩니다.

 

retail[pd.notnull(retail['CustomerID'])] = 데이터프레임 retail에서 pd.notnull(retail['CustomerID'])의 결과가 True인 행만 선택합니다. 즉! retail 데이터프레임에서 CustomerID 값이 null이 아닌 행들만 선택하여 새로운 데이터프레임을 만듭니다.

 

retail = retail[pd.notnull(retail['CustomerID'])] =

retail 변수에 null이 아닌 'CustomerID' 값을 가진 행들만 포함된 데이터프레임을 다시 할당합니다.

이렇게 하면 원래 retail 데이터프레임에서 'CustomerID' 값이 null인 행들이 모두 제거된 결과가 retail 변수에 저장됩니다.

 

 


비회원/탈퇴회원/휴면계정이 삭제된 값 갯수 확인

len(retail)

# 406829

통계정보 확인하기

describe()라는 메소드를 통해 간단한 *통계정보를 확인 할 수 있습니다.

*통계정보

 

  • count: 각 열의 데이터 수
  • mean: 평균값
  • std: 표준편차
  • min: 최소값
  • 25%: 1사분위수 (25번째 백분위수)
  • 50%: 중앙값 (50번째 백분위수)
  • 75%: 3사분위수 (75번째 백분위수)
  • max: 최대값

 

retail.describe()

여기서 보니 구매수량이 - 인것도 있게 있습니다. 이것을 이상치 라고 합니다. 이런것들을 삭제해서 데이터의 

신뢰성을 높이려고 합니다.


구입수량이 0 이하인 데이터 확인

retail[retail['Quantity'] <= 0]

사실상 구매수량이 0인것도 말이되지는 않아서 구입수량이 1이상인 것만 저장하겠습니다.


구입수량이 1상인 것들만 저장

retail = retail[retail['Quantity'] >= 1]
len(retail)

#397924

구입가격이 0 이하인 데이터 확인

retail[retail['UntiPrice']<= 0]

사실.. 구입가격이 0인것도 말이 되진 않으니 0보다 큰 데이터만 저장하겠습니다.


구입가격이  0보다 큰 데이터

retial = retail[retail['UnitPrice'] >0]
len(retail)     #397884

고객의 총 지출비용(CheckoutPrice) 파생변수 만들기

#고객의 총 지출비용(CheckoutPrice) 파생변수 만들기
# 총 지출비용(CheckoutPrice) = 가격(Unitprice) * 수량(Quantity)

retail['CheckoutPrice'] = retail['UnitPrice'] * retail['Quantity']
retail

저장된 데이터 정보 확인


 

retail.info()

날짜를 보니 계산을 할 수 없는object타입이라서 date타입으로 변경하려고 합니다.


date type 변경 후 retail로 저장

retail = ['InvoiceDate'] = pd.to_datetime(retail['InvoiceDate'])
retail.info()


데이터의 전체 매출 확인하기

total_revenue=retail['CheckoutPrice'].sum()
total_revenue

#8911407.904

각 나라별 구매 횟수

retail['Country'].value.counts()

#만약 데이터가 다 나오지 않는다면
pd.options.display.max_row = 50 
50개까지 보여줘 라는 코드


국가별 매출

#국가별 매출
#내가 푼 문제 retail.groupby('Country').count()
rev_by_countries = retail.groupby('Country')['CheckoutPrice'].sum()
rev_by_countries

#정렬하기 위해 오름차순으로 sort하겠습니다.
rev_by_countries = retail.groupby('Country')['CheckoutPrice'].sum().sort_values()
rev_by_countries


데이터 시각화 하기

 

plot = rev_by_countries.plot(kind='bar', figsize=(20, 10))
plot.set_xlabel('Country', fontsize=12)
plot.set_ylabel('Country', fontsize=12)

plot.set_title('Revenue by Country', fontsize=15)
plot.set_xticklabels(labels=rev_by_countries.index, rotation=45)

kind='bar' == 막대그래프

rotation == 각도

 


월별 매출 구하기

retail['InvoiceDate'].sort_values(ascending=False)

위 데이터로 알 수 있는것은 마지막 구매입니다.,

2011월 12월 09일 12시 50분 00초가 마지막 구매입니다.

 

일단 먼저 한자리 월(1,2,3,4,5,6,7,8,9)은 자리수가 안맞기때문에 20109 --> 201009로 바꿔주려고 합니다.

위 내용을 함수로 구현하면 아래처럼 만들어집니다.

def extract_month(date): #2011-12-09 12:50:00
    month = str(date.month) #12 문자타입이기떄문에 가능
    if date.month < 10: 
        month = '0' + month #09
    return str(date.year) + month #문자열 + 문자열 이기때문에 201112, 201109 의 형태로 출력 됨

 

위 함수를 통해서 그룹을 지어줄 수 있고 이제 합쳐서 월별 매출을 뽑을 수 있습니다.

rev_by_month = retail.set_index('InvoiceDate').groupby(extract_month)['CheckoutPrice'].sum()
rev_by_month


막대그래프를 만들어주는 함수 만들기

형광펜 친 부분은 입력받으면서 변경 가능한 변수처리값입니다.

이렇게 함수를 만들어 놓으면 그때그때 새롭게 막대그래프값을 변경할 수 있습니다.

def plot_bar(df, xlabel, ylabel, title, figsize=(20,10), fontsize=12, titlesize=15, rotation=45) :
  plot = df.plot(kind='bar', figsize=figsize)
  plot.set_xlabel(xlabel, fontsize=fontsize)
  plot.set_ylabel(ylabel, fontsize=fontsize)
  plot.set_title(title, fontsize=titlesize)
  plot.set_xticklabels(labels=df.index, rotation=rotation)
plot_bar(rev_by_month, 'Month', 'Revenue', 'Revenue By Month')

이 그래프에서 확인할 수 있는것은 상승세를 타고있는 매출입니다. 그렇지만 12월에 보면 갑자기 뚝! 떨어졌습니다.

이건 마지막 데이터가 2011-12-09라서 그렇습니다. 1/3인 매출이 저정도면 매출이 더 오를 수 있겠다 라는 생각까지 할 수 있습니다.

 


요일별 매출 구하기

rev_by_dow= retail.set_index('InvoiceDate').groupby(lambda date: date.dayofweek)['CheckoutPrice'].sum()
rev_by_dow

import numpy as np
DAY_OF_WEEK = np.array(['Mon',' Tue','Web','Thur','Fri','Sat','Sun'])
rev_by_dow.index=DAY_OF_WEEK[rev_by_dow.index]
rev_by_dow.index

rev_by_dow

plot_bar(rev_by_dow, 'Dow', 'Revenue', 'Revenue By Dow')

 


시간대별 매출 구하기

rev_by_hour = retail.set_index('InvoiceDate').groupby(lambda date: date.hour)['CheckoutPrice'].sum()
rev_by_hour


plot_bar(rev_by_hour, 'Hour', 'Revenue', 'Revenue By Hour')

 

 

데이터로부터 얻은 insight

  • 전체 매출의 약 82%가 uk에서 발생
  • 매출은 꾸준히 성장하는 것으로 예상(11년 12월 데이터는 9일까지만 포함)
  • 토요일은 영업을 하지 않음
  • 새벽 6시 오픈, 오후9시 마감예상
  • 일주일 중 목요일까지는 성장세를 보이고 이후 하락함

판매제품(StockCode)TOP10

* 단 기준은 Quantity

top_selling = retail.groupby('StockCode')['Quantity'].sum().sort_values(ascending=False)[:10]
top_selling