基於pandas python的美團某商家的評論銷售數據分析
導入相關庫
from pyecharts import Bar,Pie
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import time
數據清洗與簡單統計
- 評論數據,其中包括一下幾個字段
- 是否匿名,均價,評價(以去掉,后續會做一些關於這些評論的更為深入的分析),評價時間,交易截止時間,訂單號,套餐,上傳的圖片鏈接,質量好壞,閱讀量,回復量,評分,點贊數等。
df=pd.read_excel("all_data_meituan.xlsx")
df.drop('comment',axis=1).head(2)

df['avgPrice'].value_counts()
# 同一家店的均價應該為同一個數值,所以這列數據沒多大的意義
73 17400
Name: avgPrice, dtype: int64
df['anonymous'].value_counts()
# 匿名評價與實名評價的比例大致在5:1左右
False 14402
True 2998
Name: anonymous, dtype: int64
時間格式的轉化
def convertTime(x):
y=time.localtime(x/1000)
z=time.strftime("%Y-%m-%d %H:%M:%S",y)
return z
df["commentTime"]=df["commentTime"].apply(convertTime)
df["commentTime"].head()
0 2018-05-09 22:21:48
1 2018-06-01 19:41:31
2 2018-04-04 11:52:23
3 2018-05-01 17:12:22
4 2018-05-17 16:48:04
Name: commentTime, dtype: object
# 在excel可以用篩選器直接看到這列中的數據含有缺失值,或者在拿到數據的時候,使用df.info() 查看每列的數據信息情況
df['dealEndtime'].isna().value_counts()
# 這列數據中含有177個缺失值,其余完整
False 17223
True 177
Name: dealEndtime, dtype: int64

df['commentTime']=pd.to_datetime(df['commentTime'])
df1 = df.set_index('commentTime')
df1.resample('D').size().sort_values(ascending=False).head(100)
df2=df1.resample('M').size().to_period()
df2=df2.reset_index()
# df2.columns
# from pyecharts import Bar
bar =Bar("按月統計",width=1000,height=800)
bar.add("按月統計",df2['commentTime'],df2[0],is_label_show=True, is_datazoom_show=True,is_toolbox_show=True,is_more_utils=True)
bar

df['commentTime']=pd.to_datetime(df['commentTime'])
df['weekday'] = df['commentTime'].dt.weekday
df2= df.groupby(['weekday']).size()
# 周末吃外賣的還是教平時多了一些
from pyecharts import Bar
bar =Bar("按周統計",width=750,height=400)
weekday=["一","二","三","四","五","六","日"]
bar.add("按周統計",['周{}'.format(i) for i in weekday],df2.values,is_label_show=True, is_datazoom_show=False,is_toolbox_show=True,is_more_utils=True,is_random=True)
bar

df['commentTime']=pd.to_datetime(df['commentTime'])
df['day'] = df['commentTime'].dt.day
df2= df.groupby(['day']).size()
df2
from pyecharts import Bar
bar =Bar("按天統計",width=1000,height=400)
bar.add("按天統計",['{} 日'.format(i) for i in df2.index],df2.values,is_label_show=True, is_datazoom_show=True,is_toolbox_show=True,is_more_utils=True,is_random=True)
bar

df['commentTime']=pd.to_datetime(df['commentTime'])
df['hour'] = df['commentTime'].dt.hour
df2= df.groupby(['hour']).size()
df2
from pyecharts import Bar
bar =Bar("按時統計",width=1000,height=600)
bar.add("按時統計",['{} h'.format(i) for i in df2.index],df2.values,is_label_show=True, is_datazoom_show=True,is_toolbox_show=True,is_more_utils=True,is_random=True)
bar

# 處理數據前需要先處理缺失值
# 訂單結束時間清洗
df['dealEndtime'].fillna(method='ffill').apply(lambda x:time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(x))).head()
0 2018-06-30 14:00:00
1 2018-06-30 14:00:00
2 2018-06-30 14:00:00
3 2018-06-30 14:00:00
4 2018-06-30 14:00:00
Name: dealEndtime, dtype: object
套餐的統計
df['menu'].dropna().astype('category').value_counts()
2人午晚餐 7640
單人午晚餐 3920
學生專享午晚自助 2638
4人午/晚自助 1581
單人下午自助烤肉 639
6人午/晚自助 507
周一至周五自助烤肉/周六日及節假日自助烤肉2選1 209
單人午/晚自助 67
周一至周五自助烤肉,免費WiFi 22
Name: menu, dtype: int64

df['readCnt'].corr(df['star'])
# 評論閱讀書與客戶評價分數高低的相關性
0.05909293203205019
- 最受歡迎的套餐(2人午晚餐評價分布),基本上幾種在30,40,50,評價都還好,怪不得賣得好
df_most=df[(df["menu"]=="2人午晚餐")]['star'].value_counts().reindex(range(10,60,10))
10 329
20 533
30 2002
40 2704
50 2072
Name: star, dtype: int64

df[(df["menu"]=="單人午晚餐")]['star'].value_counts()
30 1215
40 1208
50 1093
20 298
10 106
Name: star, dtype: int64
# 學生專享午晚自助
df[(df["menu"]=="學生專享午晚自助")]['star'].value_counts()
40 954
50 863
30 529
20 191
10 101
Name: star, dtype: int64
df[(df["menu"]=="4人午/晚自助")]['star'].value_counts()
50 536
30 432
40 414
10 131
20 68
Name: star, dtype: int64
df[(df["menu"]=="單人下午自助烤肉")]['star'].value_counts()
30 208
50 169
40 144
10 98
20 20
Name: star, dtype: int64
df[(df["menu"]=="6人午/晚自助")]['star'].value_counts()
50 245
40 142
30 112
10 8
Name: star, dtype: int64
#周一至周五自助烤肉/周六日及節假日自助烤肉2選1
df[(df["menu"]=="周一至周五自助烤肉/周六日及節假日自助烤肉2選1")]['star'].value_counts()
50 87
40 66
30 46
20 10
Name: star, dtype: int64
df[(df["menu"]=="單人午/晚自助")]['star'].value_counts()
50 30
40 27
30 10
Name: star, dtype: int64
df[(df["menu"]=="周一至周五自助烤肉,免費WiFi")]['star'].value_counts().reindex(range(10,51,10)).fillna(0)
10 0.0
20 0.0
30 0.0
40 0.0
50 22.0
Name: star, dtype: float64
套餐與評價匯總
# df.groupby(['menu','star']).size().to_excel("all_menu_star.xls") 可以直接導出到excel
df.groupby(['menu','star']).size()
menu star
2人午晚餐 10 329
20 533
30 2002
40 2704
50 2072
4人午/晚自助 10 131
20 68
30 432
40 414
50 536
6人午/晚自助 10 8
30 112
40 142
50 245
單人下午自助烤肉 10 98
20 20
30 208
40 144
50 169
單人午/晚自助 30 10
40 27
50 30
單人午晚餐 10 106
20 298
30 1215
40 1208
50 1093
周一至周五自助烤肉/周六日及節假日自助烤肉2選1 20 10
30 46
40 66
50 87
周一至周五自助烤肉,免費WiFi 50 22
學生專享午晚自助 10 101
20 191
30 529
40 954
50 863
dtype: int64
df.groupby(['star','menu',]).size()
star menu
10 2人午晚餐 329
4人午/晚自助 131
6人午/晚自助 8
單人下午自助烤肉 98
單人午晚餐 106
學生專享午晚自助 101
20 2人午晚餐 533
4人午/晚自助 68
單人下午自助烤肉 20
單人午晚餐 298
周一至周五自助烤肉/周六日及節假日自助烤肉2選1 10
學生專享午晚自助 191
30 2人午晚餐 2002
4人午/晚自助 432
6人午/晚自助 112
單人下午自助烤肉 208
單人午/晚自助 10
單人午晚餐 1215
周一至周五自助烤肉/周六日及節假日自助烤肉2選1 46
學生專享午晚自助 529
40 2人午晚餐 2704
4人午/晚自助 414
6人午/晚自助 142
單人下午自助烤肉 144
單人午/晚自助 27
單人午晚餐 1208
周一至周五自助烤肉/周六日及節假日自助烤肉2選1 66
學生專享午晚自助 954
50 2人午晚餐 2072
4人午/晚自助 536
6人午/晚自助 245
單人下午自助烤肉 169
單人午/晚自助 30
單人午晚餐 1093
周一至周五自助烤肉/周六日及節假日自助烤肉2選1 87
周一至周五自助烤肉,免費WiFi 22
學生專享午晚自助 863
dtype: int64
df.groupby(['star','menu',]).size()[50]
menu
2人午晚餐 2072
4人午/晚自助 536
6人午/晚自助 245
單人下午自助烤肉 169
單人午/晚自助 30
單人午晚餐 1093
周一至周五自助烤肉/周六日及節假日自助烤肉2選1 87
周一至周五自助烤肉,免費WiFi 22
學生專享午晚自助 863
dtype: int64

# userId
# 這家店鋪有好多回頭客,萬萬沒想到
df[df['userId']!=0]['userId'].value_counts().head(40)
266045270 64
152775497 60
80372612 60
129840082 60
336387962 60
34216474 60
617772217 60
82682689 54
287219504 49
884729389 45
...
232697160 40
141718492 40
879430090 40
696143486 40
13257519 40
983797146 40
911947863 40
993057629 40
494215297 40
Name: userId, dtype: int64
df[df['userName']!="匿名用戶"]['userName'].value_counts().head(40)
xuruiss1026 64
黑發飄呀飄 60
么么噠我是你聰叔 60
jIx325233926 60
siisgood 60
vTF610712604 60
始於初見的你 60
yumengkou 54
Daaaav 49
梁子7543 45
oev575457132 40
oUI806055883 40
joF498901567 40
liE32679330 40
...
清晨cxh98 40
cBj31240225 40
天蛟Wing 40
榴蓮餡月餅 40
leeman666888 40
迅行天下 40
濱海之戀33 40
pHO437742850 40
SzX539077433 40
Name: userName, dtype: int64
評分與用戶等級匯總
df.groupby(['star','userLevel',]).size()
star userLevel
10 0 187
1 139
2 164
3 193
4 80
5 10
20 0 223
1 88
2 304
3 294
4 207
5 21
30 0 1147
1 405
2 1057
3 1230
4 570
5 165
6 20
40 0 870
1 432
2 1360
3 1751
4 1026
5 261
6 25
50 0 698
1 386
2 1167
3 1670
4 802
5 318
6 130
dtype: int64
df_level_star = df.groupby(['userLevel','star']).size()
attr = np.arange(10,60,10)
from pyecharts import Bar
bar = Bar("用戶等級與評分",title_pos="center")
df_0 = df_level_star[0].values
df_1 = df_level_star[1].values
df_2 = df_level_star[2].values
df_3 = df_level_star[3].values
df_4 = df_level_star[4].values
df_5 = df_level_star[5].values
# df_6 = df_level_star[6].values
df_6 = df_level_star[6].reindex(attr).fillna(0).values
bar.add("level 0",attr,df_0,is_label_show=True,legend_pos='right',legend_orient='vertical',label_text_size=12)
bar.add("level 1",attr,df_1,is_label_show=True,legend_pos='right',legend_orient='vertical',label_text_size=12)
bar.add("level 2",attr,df_2,is_label_show=True,legend_pos='right',legend_orient='vertical',label_text_size=12)
bar.add("level 3",attr,df_3,mark_line=["average"],mark_point=['max','min'],is_label_show=True,legend_pos='right',legend_orient='vertical',label_text_size=12)
bar.add("level 4",attr,df_4,is_label_show=True,legend_pos='right',legend_orient='vertical',label_text_size=12)
bar.add("level 5",attr,df_5,is_label_show=True,legend_pos='right',legend_orient='vertical',label_text_size=12)
bar.add("level 6",attr,df_6,is_label_show=True,legend_pos='right',legend_orient='vertical',label_text_size=12)
bar

bar = Bar("用戶等級與評分",title_pos="center",title_color="red")
attr = np.arange(10,60,10)
df_0 = df_level_star[0].values
df_1 = df_level_star[1].values
df_2 = df_level_star[2].values
df_3 = df_level_star[3].values
df_4 = df_level_star[4].values
df_5 = df_level_star[5].values
# df_6 = df_level_star[6].values
df_6 = df_level_star[6].reindex(attr).fillna(0).values
bar.add("level 0",attr,df_0,legend_pos='right',legend_orient='vertical',label_text_size=12)
bar.add("level 1",attr,df_1,legend_pos='right',legend_orient='vertical',label_text_size=12)
bar.add("level 2",attr,df_2,legend_pos='right',legend_orient='vertical',label_text_size=12)
bar.add("level 3",attr,df_3,is_stack=True,legend_pos='right',legend_orient='vertical',label_text_size=12)
bar.add("level 4",attr,df_4,is_stack=True,legend_pos='right',legend_orient='vertical',label_text_size=12)
bar.add("level 5",attr,df_5,is_stack=True,legend_pos='right',legend_orient='vertical',label_text_size=12)
bar.add("level 6",attr,df_6,is_stack=True,legend_pos='right',legend_orient='vertical',label_text_size=12)
bar

df['star'].corr(df['userLevel'])
0.14389808871897794
df_zan=df['zanCnt'].value_counts()
from pyecharts import Bar
bar=Bar("點贊統計")
bar.add("點贊分布",df_zan.index[1:],df_zan.values[1:],is_label_show=True)
bar

df.describe()

df['userLevel'].value_counts().reindex(range(7))
0 3125
1 1450
2 4052
3 5138
4 2685
5 775
6 175
Name: userLevel, dtype: int64
df_level=df['userLevel'].value_counts().reindex(range(7))
from pyecharts import Pie
pie=Pie("用戶等級分布",title_pos="center",width=900)
pie.add("levels distribution",["level "+str(i) for i in range(7)],df_level.values,is_random=True,radidus=[30,45],legend_pos='left',rosetype='area',legend_orient='vertical',is_label_show=True,label_text_size=20)
pie

- 至此基本數據分析完成,后續會開始於其評論數據的挖掘