티스토리 뷰

Untitled20

이번에는 지난 블로그에 이어서 1월 중국집 업종 통화량을 여러 각도로 보도록 해보자.

https://jfun.tistory.com/120


1. Data 확인

먼저 Data에 대한 전반적인 확인을 해 보자.

In [2]:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
In [3]:
data = pd.read_csv('CALL_CFOOD_2019_01MONTH.csv')
In [4]:
data.head()
Out[4]:
기준일 요일 성별 연령대 시도 시군구 읍면동 업종 통화건수
0 20190101 40대 서울특별시 강남구 대치동 중국집 5
1 20190101 30대 서울특별시 강남구 신사동 중국집 5
2 20190101 30대 서울특별시 강남구 삼성동 중국집 44
3 20190101 10대 서울특별시 강남구 논현동 중국집 5
4 20190101 40대 서울특별시 강남구 일원동 중국집 5

모든 날짜가 나타나 있는지 확인하자

In [5]:
d2 =data['기준일'].unique()
d2, len(d2)
Out[5]:
(array([20190101, 20190102, 20190103, 20190104, 20190105, 20190106,
        20190107, 20190108, 20190109, 20190110, 20190111, 20190112,
        20190113, 20190114, 20190115, 20190116, 20190117, 20190118,
        20190119, 20190120, 20190121, 20190122, 20190123, 20190124,
        20190125, 20190126, 20190127, 20190128, 20190129, 20190130,
        20190131], dtype=int64), 31)

날짜를 숫자열이 아닌 날짜열로 바꿔보자

In [6]:
data.dtypes
Out[6]:
기준일      int64
요일      object
성별      object
연령대     object
시도      object
시군구     object
읍면동     object
업종      object
통화건수     int64
dtype: object
In [7]:
data['기준일']=pd.to_datetime(data['기준일'],format='%Y%m%d')
data.head()
Out[7]:
기준일 요일 성별 연령대 시도 시군구 읍면동 업종 통화건수
0 2019-01-01 40대 서울특별시 강남구 대치동 중국집 5
1 2019-01-01 30대 서울특별시 강남구 신사동 중국집 5
2 2019-01-01 30대 서울특별시 강남구 삼성동 중국집 44
3 2019-01-01 10대 서울특별시 강남구 논현동 중국집 5
4 2019-01-01 40대 서울특별시 강남구 일원동 중국집 5

대부분의 날짜 형식은 datetime을 이용하면 날짜열로 바꿔줄수 있다.
제대로 안되는경우 문자열로 바꿔준 다음 날짜열로 바꿔보던가, 아니면 format을 이용해본다.

2. 빠진 정보가 없는지 확인해 보자.

null값 판단방법1

In [8]:
data.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 28406 entries, 0 to 28405
Data columns (total 9 columns):
기준일     28406 non-null datetime64[ns]
요일      28406 non-null object
성별      28406 non-null object
연령대     28406 non-null object
시도      28406 non-null object
시군구     28406 non-null object
읍면동     28406 non-null object
업종      28406 non-null object
통화건수    28406 non-null int64
dtypes: datetime64[ns](1), int64(1), object(7)
memory usage: 2.0+ MB
  • RangeIndex: 29850 entries, 0 to 29849 0부터 29849까지 총 29850개의 데이터가 있음을 의미
  • 모든 데이터가 29850개 이머 non-null이므로 데이터가 빠짐 없이 존재함을 알 수 있다.

null값 판단방법2

In [9]:
d1 = data.isnull()
d1.head()
Out[9]:
기준일 요일 성별 연령대 시도 시군구 읍면동 업종 통화건수
0 False False False False False False False False False
1 False False False False False False False False False
2 False False False False False False False False False
3 False False False False False False False False False
4 False False False False False False False False False

df.isnull()을 하면 모든 데이터에 대해서 null값일 경우 True, 아니면 False로 처리한다.
반면 df.notnull()을 하면 반대로 처리한다.

In [10]:
d1.sum()
Out[10]:
기준일     0
요일      0
성별      0
연령대     0
시도      0
시군구     0
읍면동     0
업종      0
통화건수    0
dtype: int64

위에서 bull값으로 처리한 데이터를 열(column)별로 더하는 작업이다. True=1, False=0을 의미한다.
더했을때 값이 0이 나오므로 이를 통해서도 null값이 없음을 알 수 있다.

3.어떻게 분석을 해볼까? 도메인 지식!

이제 이 데이터를 어떻게 다룰지 방향을 잡아보자. 데이터를 다룰때는 도메인 지식을 가지고 있어야지만 데이터에 의미를 부여할 수 있다. 우리가 알고 있는 약간의 지식을 활용하여 질문을 던져보자.

  1. 통화건수에 요일은 영향을 미칠까?
    금요일이나 토요일에 가장 많은 주문을 할 것 같다.

  2. 연령에 따라 통화 건수의 차이가 클까?
    금전적으로 여유가 있는 30대 40대가 더 많은 주문을 할 것 같다.

4.분석을 위해 Data를 구축해 보자

이제 Data를 group by를 이용하여 요약해 보자.
요일은 보기 좋게 순서대로 나오도록 설정하자.

인덱서를 사용해 나타내보자.
loc : 라벨값 기반의 2차원 인덱싱

In [41]:
week = data['통화건수'].groupby(data['요일'])
W = week.sum()
week_s = []
for w in ['월','화','수','목','금','토','일']:
    week_s.append([w,W[w]])
W1=pd.DataFrame(week_s)

W1.rename(columns = {W1.columns[0] : '요일',
                     W1.columns[1] : '통화건수'}, inplace = True)
W1
Out[41]:
요일 통화건수
0 45420
1 57898
2 60448
3 62243
4 51288
5 58141
6 55812

목,수,토,일 요일에 판매량이 높음을 알 수 있다.

연령대별로 요약해보자

In [12]:
age = data['통화건수'].groupby(data['연령대'])
age.sum()
Out[12]:
연령대
10대       15683
20대       46480
30대       84884
40대      113050
50대       76784
60대이상     54369
Name: 통화건수, dtype: int64

40대의 중국집 통화량이 압도적으로 높음을 볼 수 있다. 그 다음은 30대와 50대.

피벗테이블을 이용해 요일과 연령대 정보를 통합하여 통화건수 정보를 추출해 보았다.

In [13]:
data1=data.pivot_table(values='통화건수',index='요일',columns='연령대',aggfunc=sum,margins=True).loc[['월','화','수','목','금','토','일']]
data1.head()
Out[13]:
연령대 10대 20대 30대 40대 50대 60대이상 All
요일
2022 5568 9683 12392 9098 6657 45420
2264 7113 12277 16669 11436 8139 57898
2625 7345 12981 16941 12061 8495 60448
2610 7456 13223 17831 12352 8771 62243
2211 6191 11219 14731 9793 7143 51288

순서를 세기 위해 'All' 컬럼을 삭제하자.

In [14]:
data2=data1.drop('All',axis=1)
data2
Out[14]:
연령대 10대 20대 30대 40대 50대 60대이상
요일
2022 5568 9683 12392 9098 6657
2264 7113 12277 16669 11436 8139
2625 7345 12981 16941 12061 8495
2610 7456 13223 17831 12352 8771
2211 6191 11219 14731 9793 7143
2105 6432 12895 17557 11287 7865
1846 6375 12606 16929 10757 7299
In [15]:
data2.idxmax(axis=0)
Out[15]:
연령대
10대      수
20대      목
30대      목
40대      목
50대      목
60대이상    목
dtype: object
In [16]:
data2.idxmax(axis=1)
Out[16]:
요일
월    40대
화    40대
수    40대
목    40대
금    40대
토    40대
일    40대
dtype: object

이 정보를 통해 40대가 가장 많이 주문 했음을, 그리고 목요일에 가장 많이 주문 했음을 알 수 있다.

한눈에 보기 좋게 전체 데이터를 나열해보자.

In [17]:
data3=np.array(data2)

I=[]
labels1 = ['10대','20대','30대','40대','50대','60대이상']
labels2 = ['월','화','수','목','금','토','일']

for i in range(6):
    for j in range(7):
        I.append([data3[j,i], labels1[i], labels2[j]])

data4 = pd.DataFrame(I)

data4.rename(columns={data4.columns[0] : '총 통화건수',
                      data4.columns[1] : '연령대',
                      data4.columns[2] : '요일'}, inplace=True)

data4.sort_values('총 통화건수', ascending=False).head(15)
Out[17]:
총 통화건수 연령대 요일
24 17831 40대
26 17557 40대
23 16941 40대
27 16929 40대
22 16669 40대
25 14731 40대
17 13223 30대
16 12981 30대
19 12895 30대
20 12606 30대
21 12392 40대
31 12352 50대
15 12277 30대
30 12061 50대
29 11436 50대

40대 다음으로 30대 50대 순으로 주문량이 많았음을 한눈에 알아볼 수 있다.

30대 40대의 중국집 주문량이 많은 이유는 금전적으로 여유가 있기 때문인것 같다. 그리고 지난번 치킨 분석때는 20대가 3번째로 많았던 것과는 다르게 50대 주문량이 많은 이유는, 치킨은 술과 함께 먹는 경우도 많지만 중국집 음식은 주로 식사로 먹기 때문이다.

In [18]:
import matplotlib.pyplot as plt
import seaborn as sns
from scipy import stats
In [19]:
data["year"] = data["기준일"].dt.year
data["month"] = data["기준일"].dt.month
data["day"] = data["기준일"].dt.day

data.shape
Out[19]:
(28406, 12)
In [20]:
data.head()
Out[20]:
기준일 요일 성별 연령대 시도 시군구 읍면동 업종 통화건수 year month day
0 2019-01-01 40대 서울특별시 강남구 대치동 중국집 5 2019 1 1
1 2019-01-01 30대 서울특별시 강남구 신사동 중국집 5 2019 1 1
2 2019-01-01 30대 서울특별시 강남구 삼성동 중국집 44 2019 1 1
3 2019-01-01 10대 서울특별시 강남구 논현동 중국집 5 2019 1 1
4 2019-01-01 40대 서울특별시 강남구 일원동 중국집 5 2019 1 1
In [21]:
%matplotlib inline

import platform

path = "c:/Windows/Fonts/malgun.ttf"
from matplotlib import font_manager, rc
if platform.system() == 'Darwin':
    rc('font', family='AppleGothic')
elif platform.system() == 'Windows':
    font_name = font_manager.FontProperties(fname=path).get_name()
    rc('font', family=font_name)
else:
    print('Unknown system... sorry~~~~')
In [22]:
w2=[]

for i in ['월','화','수','목','금','토','일']:
    
    k=np.sum(data['요일']==i)
    
    w2.append(k)

w2
Out[22]:
[3568, 4362, 4560, 4562, 3700, 3886, 3768]
In [23]:
W3 = pd.DataFrame({'요일' : ['월','화','수','목','금','토','일'], '통화건수' : w2})
W3
Out[23]:
요일 통화건수
0 3568
1 4362
2 4560
3 4562
4 3700
5 3886
6 3768
In [44]:
sex = data['통화건수'].groupby(data['성별'])
S = sex.sum()
sex1 = []
for s in ['남','여']:
    sex1.append([s,S[s]])
S1=pd.DataFrame(sex1)

S1.rename(columns = {S1.columns[0] : '성별',
                     S1.columns[1] : '통화건수'}, inplace = True)
S1
Out[44]:
성별 통화건수
0 217550
1 173700
In [46]:
age = data['통화건수'].groupby(data['연령대'])
A = age.sum()
age1 = []
for a in ['10대','20대','30대','40대','50대','60대이상']:
    age1.append([a,A[a]])
A1=pd.DataFrame(age1)

A1.rename(columns = {A1.columns[0] : '연령대',
                     A1.columns[1] : '통화건수'}, inplace = True)
A1
Out[46]:
연령대 통화건수
0 10대 15683
1 20대 46480
2 30대 84884
3 40대 113050
4 50대 76784
5 60대이상 54369
In [47]:
figure, ((ax1,ax2),(ax3,ax4)) = plt.subplots(nrows=2, ncols=2)
figure.set_size_inches(18,8)

sns.barplot(data=data, x="day", y="통화건수", ax=ax1)
sns.barplot(data=W1, x="요일", y="통화건수", ax=ax2)
sns.barplot(data=S1, x="성별", y="통화건수", ax=ax3)
sns.barplot(data=A1, x="연령대", y="통화건수", ax=ax4)
Out[47]:
<matplotlib.axes._subplots.AxesSubplot at 0x1a4dce46dd8>
In [51]:
Re = np.unique(data['시군구'])
region = data['통화건수'].groupby(data['시군구'])

R = region.sum()
region1 = []
for r in Re:
    region1.append([r,R[r]])
R1=pd.DataFrame(region1)

R1.rename(columns = {R1.columns[0] : '시군구',
                     R1.columns[1] : '통화건수'}, inplace = True)
R1.head()
Out[51]:
시군구 통화건수
0 강남구 41356
1 강동구 17632
2 강북구 16393
3 강서구 28260
4 관악구 2801
In [50]:
figure.set_size_inches(18,8)
sns.barplot(data=R1, x="시군구", y="통화건수")
plt.xticks(rotation=90)
Out[50]:
(array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
        17, 18, 19, 20, 21, 22, 23, 24]),
 <a list of 25 Text xticklabel objects>)
In [72]:
ddong = np.unique(data['읍면동'])
region2 = data['통화건수'].groupby(data['읍면동'])

R_ = region2.sum()
region3 = []
J=[]
for r in ddong:
    if R_[r]>1000:
        region3.append([r,R_[r]])
    else:
        J.append(r)
    
R2=pd.DataFrame(region3)

R2.rename(columns = {R2.columns[0] : '읍면동',
                     R2.columns[1] : '통화건수'}, inplace = True)
R2.head()
Out[72]:
읍면동 통화건수
0 가락동 3061
1 가산동 3109
2 가양동 5170
3 개봉동 5563
4 공릉동 4438
In [81]:
fig = plt.figure(figsize=[50,20])
sns.barplot(data=R2, x="읍면동", y="통화건수")
plt.xticks(fontsize=40,rotation=90)
print('')


공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함