柚子快報激活碼778899分享:數(shù)據(jù)可視化之廣電大數(shù)據(jù)
柚子快報激活碼778899分享:數(shù)據(jù)可視化之廣電大數(shù)據(jù)
完整代碼:(數(shù)據(jù)處理部分)
# 代碼6-1
import pandas as pd
data_raw = pd.read_csv('media_index.csv', encoding='gbk', header='infer')
payevents = pd.read_csv('mmconsume_payevents.csv', sep=',',
encoding='gbk', header='infer')
print(data_raw.shape, payevents.shape)
# 代碼6-2
media = pd.read_csv('media_index.csv', encoding='gbk', header='infer')
# 將“-高清”替換為空
media['station_name'] = media['station_name'].str.replace('-高清', '')
# 過濾特殊線路、政企用戶
media = media.loc[(media.owner_code != 2)&(media.owner_code != 9)&
(media.owner_code != 10), :]
print('查看過濾后的特殊線路的用戶:', media.owner_code.unique())
media = media.loc[(media.owner_name != 'EA級')&(media.owner_name != 'EB級')&
(media.owner_name != 'EC級')&(media.owner_name != 'ED級')&
(media.owner_name != 'EE級'), :]
print('查看過濾后的政企用戶:', media.owner_name.unique())
# 對開始時間進行拆分
# 檢查數(shù)據(jù)類型
type(media.loc[0, 'origin_time'])
# 轉化為時間類型
media['end_time'] = pd.to_datetime(media['end_time'])
media['origin_time'] = pd.to_datetime(media['origin_time'])
# 提取秒
media['origin_second'] = media['origin_time'].dt.second
media['end_second'] = media['end_time'].dt.second
# 篩選數(shù)據(jù)
ind1 = (media['origin_second'] == 0) & (media['end_second'] == 0)
media1 = media.loc[~ind1, :]
# 基于開始時間和結束時間的記錄去重
media1.end_time = pd.to_datetime(media1.end_time)
media1.origin_time = pd.to_datetime(media1.origin_time)
media1 = media1.drop_duplicates(['origin_time', 'end_time'])
# 隔夜處理
# 去除開始時間,結束時間為空值的數(shù)據(jù)
media1 = media1.loc[media1.origin_time.dropna().index, :]
media1 = media1.loc[media1.end_time.dropna().index, :]
# 創(chuàng)建星期特征列
media1['星期'] = media1.origin_time.apply(lambda x: x.weekday()+1)
dic = {1:'星期一', 2:'星期二', 3:'星期三', 4:'星期四', 5:'星期五', 6:'星期六', 7:'星期日'}
for i in range(1, 8):
ind = media1.loc[media1['星期'] == i, :].index
media1.loc[ind, '星期'] = dic[i]
# 查看有多少觀看記錄是隔天的,隔天的進行隔天處理
a = media1.origin_time.apply(lambda x :x.day)
b = media1.end_time.apply(lambda x :x.day)
sum(a != b)
media2 = media1.loc[a != b, :].copy() # 需要做隔天處理的數(shù)據(jù)
def geyechuli_xingqi(x):
dic = {'星期一':'星期二', '星期二':'星期三', '星期三':'星期四', '星期四':'星期五',
'星期五':'星期六', '星期六':'星期日', '星期日':'星期一'}
return x.apply(lambda y: dic[y.星期], axis=1)
media1.loc[a != b, 'end_time'] = media1.loc[a != b, 'end_time'].apply(lambda x:
pd.to_datetime('%d-%d-%d 23:59:59'%(x.year, x.month, x.day)))
media2.loc[:, 'origin_time'] = pd.to_datetime(media2.end_time.apply(lambda x:
'%d-%d-%d 00:00:01'%(x.year, x.month, x.day)))
media2.loc[:, '星期'] = geyechuli_xingqi(media2)
media3 = pd.concat([media1, media2])
media3['origin_time1'] = media3.origin_time.apply(lambda x:
x.second + x.minute * 60 + x.hour * 3600)
media3['end_time1'] = media3.end_time.apply(lambda x:
x.second + x.minute * 60 + x.hour * 3600)
media3['wat_time'] = media3.end_time1 - media3.origin_time1 # 構建觀看總時長特征
# 清洗時長不符合的數(shù)據(jù)
# 剔除下次觀看的開始時間小于上一次觀看的結束時間的記錄
media3 = media3.sort_values(['phone_no', 'origin_time'])
media3 = media3.reset_index(drop=True)
a = [media3.loc[i+1, 'origin_time'] < media3.loc[i, 'end_time'] for i in range(len(media3)-1)]
a.append(False)
aa = pd.Series(a)
media3 = media3.loc[~aa, :]
# 去除小于4S的記錄
media3 = media3.loc[media3['wat_time'] > 4, :]
# 保存貼標簽用
media3.to_csv('media3.csv', na_rep='NaN', header=True, index=False)
# 查看連續(xù)觀看同一頻道的時長是否大于3h
# 發(fā)現(xiàn)這2000個用戶不存在連續(xù)觀看大于3h的情況
media3['date'] = media3.end_time.apply(lambda x :x.date())
media_group = media3['wat_time'].groupby([media3['phone_no'],
media3['date'],
media3['station_name']]).sum()
media_group = media_group.reset_index()
media_g = media_group.loc[media_group['wat_time'] >= 10800, ]
media_g['time_label'] = 1
o = pd.merge(media3, media_g, left_on=['phone_no', 'date', 'station_name'],
right_on=['phone_no', 'date', 'station_name'], how='left')
oo = o.loc[o['time_label'] == 1, :]
# 代碼6-3
payevents = pd.read_csv('mmconsume_payevents.csv', sep=',',
encoding='gbk', header='infer')
payevents.columns = ['phone_no', 'owner_name', 'event_time', 'payment_name',
'login_group_name', 'owner_code']
# 過濾特殊線路、政企用戶
payevents = payevents.loc[(payevents.owner_code != 2
)&(payevents.owner_code != 9
)&(payevents.owner_code != 10), :] # 去除特殊線路數(shù)據(jù)
print('查看過濾后的特殊線路的用戶:', payevents.owner_code.unique())
payevents = payevents.loc[(payevents.owner_name != 'EA級'
)&(payevents.owner_name != 'EB級'
)&(payevents.owner_name != 'EC級'
)&(payevents.owner_name != 'ED級'
)&(payevents.owner_name != 'EE級'), :]
print('查看過濾后的政企用戶:', payevents.owner_name.unique())
payevents.to_csv('payevents2.csv', na_rep='NaN', header=True, index=False)
了解項目背景
1、隨著科技的發(fā)展,現(xiàn)在人們觀看電視節(jié)目的方式越來越多,給人們帶了很多便利。人們不僅可以使用傳統(tǒng)的電視機觀看電視節(jié)目,而且可以通過網絡觀看電視節(jié)目,這樣使得運營商、用戶、網絡之間產生了一些交互關系。為了更改的為用戶提供服務,并提高收益和收視率,需要對廣電數(shù)據(jù)進行分析。
2、目前某廣播電視網絡運營集團已建成完整覆蓋廣東省各區(qū)(縣級市)的有線傳輸與無線傳輸互為延伸、互為補充的廣電寬帶信息網絡,實現(xiàn)了城區(qū)全程全網的雙向覆蓋,為廣大市民提供有線數(shù)字電視、互聯(lián)網接入服務、高清互動電視、移動數(shù)字電視、手機電視、信息內容集成等多樣化、跨平臺的信息服務。
3、每個家庭收看電視節(jié)目都需要通過機頂盒進行收視節(jié)目的接收和交互行為(如點播行為、回看行為)的發(fā)送,并將交互行為數(shù)據(jù)發(fā)送至每個區(qū)域的光機設備(進行數(shù)據(jù)傳遞的中介),光機設備會匯集該區(qū)域的信息數(shù)據(jù),再發(fā)送至數(shù)據(jù)中心進行整合、存儲。信息數(shù)據(jù)的收集過程如圖所示。
4、由于已建成的大數(shù)據(jù)平臺積累了大量用戶基礎信息和用戶觀看記錄信息等數(shù)據(jù),所以在此基礎上進一步挖掘出數(shù)據(jù)價值,可以提升客戶體驗,并提出精準的營銷建議,采取有效應對措施,實現(xiàn)增加用戶黏度,從而使用戶與企業(yè)之間建立穩(wěn)定交互關系,實現(xiàn)客戶鏈式反應增值。
熟悉數(shù)據(jù)情況
1、在大數(shù)據(jù)平臺中存有用戶的基礎信息(安裝地址等)、訂單數(shù)據(jù)(產品訂購、退訂信息)、工單數(shù)據(jù)(報裝、故障、投訴、咨詢等工單信息)、收費數(shù)據(jù)(繳費、托收等各渠道支付信息)、賬單數(shù)據(jù)(月租賬單收入數(shù)據(jù))、雙向互動電視平臺收視行為數(shù)據(jù)(直播、點播、回看、廣告的收視數(shù)據(jù))、用戶上網設備的指標狀態(tài)數(shù)據(jù)(上下行電平、信噪比、流量等),共7種數(shù)據(jù)。
2、由于每個用戶收視習慣、興趣愛好存在差異性,本次抽取了2000個樣本用戶在2018年5月12日至2018年6月12日的收視行為信息數(shù)據(jù)和收費數(shù)據(jù),并對兩份數(shù)據(jù)表進行脫敏處理。?
3、各數(shù)據(jù)表及特征說明如表所示。
熟悉項目流程
如何將豐富的電視產品與用戶個性化需求實現(xiàn)最優(yōu)匹配,是廣電行業(yè)急需解決的重要問題。用戶對電視產品的需求不同,在挑選搜尋想要的信息過程中,需要花費大量的時間,這種情況的出現(xiàn)造成了用戶的不斷流失,對企業(yè)造成巨大的損失。廣電大數(shù)據(jù)可視化的主要步驟如下。
1、抽取2000個用戶在2018年5月12日至2018年6月12日的收視行為信息數(shù)據(jù)和收費數(shù)據(jù)
2、對抽取的數(shù)據(jù)進行數(shù)據(jù)清洗
3、對清洗后的數(shù)據(jù)進行可視化分析,包括用戶分析、頻道分析、時長分析、周時長分析和用戶支付方式分析等
4、撰寫項目分析報告??
?讀取與處理廣播電視數(shù)據(jù)
讀取數(shù)據(jù)
1、在項目的原始數(shù)據(jù)中可能會出現(xiàn)部分噪聲數(shù)據(jù),如重復值、異常值、冗余數(shù)據(jù)等,將會對后續(xù)的可視化分析結果造成影響。因此,需要在Python中讀取廣播電視數(shù)據(jù),并對數(shù)據(jù)進行清洗。
2、通過pandas庫中的read_csv()函數(shù)讀取用戶收視行為數(shù)據(jù)和收費數(shù)據(jù)。結果如表所示。?
?
清洗數(shù)據(jù)
1、通過讀取數(shù)據(jù)的運行結果可知,用戶收視行為數(shù)據(jù)和收費數(shù)據(jù)存在的數(shù)據(jù)量相對較多,其中可能存在一定的缺失值、異常值等數(shù)據(jù),且不同的數(shù)據(jù)存在的問題可能會不一致。
2、因此需要根據(jù)不同數(shù)據(jù)中存在的不同情況,分別對行為信息數(shù)據(jù)和收費數(shù)據(jù)進行清洗處理 。
1、收視行為信息數(shù)據(jù)
1、在用戶的收視行為信息數(shù)據(jù)(media_index)中存在直播頻道名稱(station_name)中含有“-高清”字段,如“江蘇衛(wèi)視-高清”與“江蘇衛(wèi)視”等。由于本項目中暫不分開考慮是否為高清頻道的情況,所以需要將直播頻道名稱中“-高清”字段替換為空?!皬V州電視”與“廣州電視-高清”
?
2、從業(yè)務角度分析,該廣電運營商主要面向的對象是眾多的普通家庭,而收視行為信息數(shù)據(jù)中存在特殊線路和政企類的用戶,即用戶等級號(owner_code)為02、09、10的數(shù)據(jù)與用戶等級名稱(owner_name)為EA級、EB級、EC級、ED級、EE級的數(shù)據(jù)。因為特殊線路主要是起到演示、宣傳等作用,這部分數(shù)據(jù)對于分析用戶行為意義不大,并且會影響分析結果的準確性,所以需要將這部分數(shù)據(jù)刪除。而政企類數(shù)據(jù)暫時不做分析,同樣也需要刪除。?
?
?3、在收視行為信息數(shù)據(jù)中存在有同一用戶開始觀看時間(origin_time)結束觀看時間(end_time)重復的記錄數(shù)據(jù),而且觀看的節(jié)目不同,如圖所示,這可能是由于數(shù)據(jù)收集設備導致的。經過與廣電運營商的業(yè)務人員溝通之后,默認保留第一條收視記錄,因此需要基于數(shù)據(jù)中開始觀看時間(origin_time)和結束時間(end_time)的記錄進行去重。
?
?4、在收視行為信息數(shù)據(jù)中存在跨夜的記錄數(shù)據(jù),如開始觀看時間和結束觀看時間分別為05-12 23:45:00和05-13 00:31:00,如圖所示。
5、在對用戶收視行為信息數(shù)據(jù)進行分析時發(fā)現(xiàn),存在用戶的觀看時間極短的現(xiàn)象,如圖所示?,這部分觀看時間過短可能是因為用戶在觀看中換頻道。經過與廣電運營商的業(yè)務人員溝通之后,選擇觀看時長小于4秒作為時間極短的判斷閾值,將小于閾值的數(shù)據(jù)稱為異常行為數(shù)據(jù),統(tǒng)一進行刪除處理。
?6、此外,還存在用戶較長時間觀看同一頻道的現(xiàn)象,這部分觀看時間過長可能是因為用戶在收視行為結束后,未能及時關閉機頂盒或其他原因造成。這類用戶在廣電運營大數(shù)據(jù)平臺中數(shù)據(jù)記錄中,未進行收視互動的情況下,節(jié)目開始觀看時間和結束觀看時間的單位秒為00的整點(秒)播放。經過與廣電運營商的業(yè)務人員溝通之后,選擇將直播收視數(shù)據(jù)中開始觀看時間和結束觀看時間的單位秒為00的記錄刪除。
7、最后,發(fā)現(xiàn)數(shù)據(jù)有下次觀看的開始觀看時間小于上一次觀看的結束觀看時間的記錄,這種異常數(shù)據(jù)的產生是由于數(shù)據(jù)收集設備異常導致的,需要進行刪除處理
8、綜合上述業(yè)務數(shù)據(jù)處理方法,清洗收視行為信息數(shù)據(jù)的具體步驟如下。
將直播頻道名稱(station_name)中“-高清”替換為空刪除特殊線路的用戶,用戶等級號(owner_code)為02、09、10的數(shù)據(jù)刪除政企用戶,用戶等級名稱(owner_name)為EA級、EB級、EC級、ED級、EE級的數(shù)據(jù)基于數(shù)據(jù)中開始觀看時間(origin_time)和結束觀看時間(end_time)的記錄去重隔夜處理,將跨夜的收視數(shù)據(jù)分成兩天即兩條收視數(shù)據(jù)刪除觀看同一頻道累計連續(xù)觀看小于4秒的記錄刪除直播收視數(shù)據(jù)中開始觀看時間和結束時間的單位秒為00的收視數(shù)據(jù)刪除下次觀看記錄的開始觀看時間小于上一次觀看記錄的結束觀看時間的記錄
代碼:3分鐘左右
# 讀取數(shù)據(jù)
import pandas as pd
data_xin = pd.read_csv('media_index.csv', encoding='gbk', header='infer')
data_shou = pd.read_csv('mmconsume_payevents.csv', sep=',',encoding='gbk', header='infer')
#GBK編碼是中文編碼,UTF-8編碼是多字符集編碼,支持多國語言
#header:是否將原數(shù)據(jù)集中的第一行作為表頭,默認是,并將第一行作為變量名稱:如果原始數(shù)據(jù)中沒有表頭,該參數(shù)需要設置成None
# header='infer'默認以第一行作為標題, header=None不要以第一行作為標題
# sep分隔符。 csv文件的分隔符就是,可以默認。
print(data_xin.shape,data_shou.shape)#shape:讀取矩陣或數(shù)組的長度
# 信息數(shù)據(jù)
# 1、將“-高清”替換為空
data_xin['station_name'] = data_xin['station_name'].str.replace('-高清', '')
#一.replace():替換函數(shù)
#基本用法:對象.replace(rgExp,replaceText,max)
#其中,rgExp和replaceText是必須要有的,max是可選的參數(shù),可以不加。
#rgExp是指 String 對象或文字;replaceText是一個String 對象或字符串文字;max是一個數(shù)字。
# 對于一個對象,在對象的每個rgExp都替換成replaceText,從左到右最多max次。
# 2、過濾特殊線路、政企用戶
media = data_xin.loc[(data_xin.owner_code != 2)&(data_xin.owner_code != 9)&(data_xin.owner_code != 10), :]
print('查看過濾后的特殊線路的用戶:', media.owner_code.unique())
media = media.loc[(media.owner_name != 'EA級')&(media.owner_name != 'EB級')&
(media.owner_name != 'EC級')&(media.owner_name != 'ED級')&
(media.owner_name != 'EE級'), :]
print('查看過濾后的政企用戶:', media.owner_name.unique())
#data.loc[(data['A']==0)&(data['B']==2)] #提取data數(shù)據(jù)(多個篩選條件)
#data.loc[:,:]:提取所有數(shù)據(jù)
#unique():去除其中重復的元素,并按元素由大到小返回一個新的無元素重復的元組或者列表
#第三步的前提操作
# 對開始時間進行拆分
# 檢查數(shù)據(jù)類型:origin_time:開始觀看時間
time = media.loc[0, 'origin_time']#取“origin_time”列中的第一個數(shù)
type(time)#type:類型
#loc就是location,而iloc就是integer location。顧名思義,后者參數(shù)只能是整數(shù)。
#.loc先行后列,中間用逗號(,)分割,例如取 a 和 A 對應的數(shù)據(jù):df.loc['a','A']
#----------------------------------------------------------------
# 轉化為時間類型:Pandas日期數(shù)據(jù)處理函數(shù) to_datetime()
# 將時間格式的字符串轉換為標準的時間
media['end_time'] = pd.to_datetime(media['end_time'])
media['origin_time'] = pd.to_datetime(media['origin_time'])
#to_datetime函數(shù)可以用來批量處理日期數(shù)據(jù)轉換,可以將日期數(shù)據(jù)轉換成你需要的各種格式
#----------------------------------------------------------------
# 提取秒
#提取時間中的秒,將其賦給新列秒
#dt:日期時間數(shù)據(jù)
#python的日期抽?。篸t.hour、dt.minute、dt.second、dt.microsecond:獲取時、分、秒、微秒
media['origin_second'] = media['origin_time'].dt.second
media['end_second'] = media['end_time'].dt.second
# 篩選數(shù)據(jù)
#“~”符號在這里是取反的意思,表示對 df[col].isin(list) 這句返回的值取反
a = (media['origin_second'] == 0) & (media['end_second'] == 0)
media1 = media.loc[~a, :]#所有的列
# 3、基于開始時間和結束時間的記錄去重
# to_datetime:將時間格式的字符串轉換為標準的時間
#drop_duplicates 是 pandas 庫中的一個函數(shù),用于刪除數(shù)據(jù)框中的重復行。
# 該函數(shù)默認會對整個數(shù)據(jù)框進行重復行的刪除,也可以通過指定特定的列來確定重復行。
media1.end_time = pd.to_datetime(media1.end_time)
media1.origin_time = pd.to_datetime(media1.origin_time)
media1 = media1.drop_duplicates(['origin_time', 'end_time'])
# 第四步的前提處理:隔夜處理
# 去除開始時間,結束時間為空值的數(shù)據(jù)
#Python處理數(shù)據(jù)中的空值(缺失值)時用到的dropna()函數(shù)
#index:索引
media1 = media1.loc[media1.origin_time.dropna().index, :]
media1 = media1.loc[media1.end_time.dropna().index, :]
# 創(chuàng)建星期特征列
#lambda函數(shù)也叫匿名函數(shù)
#apply():當一個函數(shù)的參數(shù)存在于一個元組或者一個字典中時,用來間接的調用這個函數(shù),并肩元組或者字典中的參數(shù)按照順序傳遞給參數(shù)
#datetime.weedak()方法的返回值為[0,6]之間的整數(shù),分別代表周一到周日
media1['星期'] = media1.origin_time.apply(lambda x: x.weekday()+1)
rq = {1:'星期一', 2:'星期二', 3:'星期三', 4:'星期四', 5:'星期五', 6:'星期六', 7:'星期日'}#字典
for i in range(1, 8):#表示從1到9循環(huán)遍歷,每次循環(huán)的變量名為i
# 篩選出數(shù)據(jù)框 media1 中星期為 i 的行,并返回這些行的索引。其中的 : 表示返回所有列的數(shù)據(jù)
xq = media1.loc[media1['星期'] == i, :].index
#這行代碼是在 Pandas 庫中的 DataFrame 對象 media1 的 xq 行的“星期”列中插入 rq 列表中第 i 個元素的值。
# 具體來說,它是在 DataFrame 的 xq 行的“星期”列中將值設置為 rq[i]
media1.loc[xq, '星期'] = rq[i]
# 4、查看有多少觀看記錄是隔天的,隔天的進行隔天處理
#象 media1 中 origin_time 列的日期取出來,并轉換為 day(即日期中的天數(shù))的操作
b = media1.origin_time.apply(lambda x :x.day)
c = media1.end_time.apply(lambda x :x.day)
sum(b != c)
# copy()淺度復制:復制的數(shù)會隨著被復制數(shù)的嵌套序列的元素的改變而改變;功能:將一個列表復制給另一個列表
media2 = media1.loc[b != c, :].copy() # 需要做隔天處理的數(shù)據(jù)
def geyechuli(x):
dic = {'星期一':'星期二', '星期二':'星期三', '星期三':'星期四', '星期四':'星期五',
'星期五':'星期六', '星期六':'星期日', '星期日':'星期一'}
#axis=0 表示按照行的方向;axis=1 表示按照列的方向
return x.apply(lambda y: dic[y.星期], axis=1)
media1.loc[b != c, 'end_time'] = media1.loc[b != c, 'end_time'].apply(lambda x:
pd.to_datetime('%d-%d-%d 23:59:59'%(x.year, x.month, x.day)))
media2.loc[:, 'origin_time'] = pd.to_datetime(media2.end_time.apply(lambda x:
'%d-%d-%d 00:00:01'%(x.year, x.month, x.day)))
media2.loc[:, '星期'] = geyechuli(media2)
media3 = pd.concat([media1, media2])#concat:拼接
media3['origin_time1'] = media3.origin_time.apply(lambda x:
x.second + x.minute * 60 + x.hour * 3600)
media3['end_time1'] = media3.end_time.apply(lambda x:
x.second + x.minute * 60 + x.hour * 3600)
media3['wat_time'] = media3.end_time1 - media3.origin_time1 # 構建觀看總時長特征
# 清洗時長不符合的數(shù)據(jù)
# 6、剔除下次觀看的開始時間小于上一次觀看的結束時間的記錄
#sort_values()將數(shù)據(jù)集依照某個字段中的數(shù)據(jù)進行排序,該函數(shù)即可根據(jù)指定列數(shù)據(jù)也可根據(jù)指定行的數(shù)據(jù)排序。
#phone_no:用戶名
media3 = media3.sort_values(['phone_no', 'origin_time'])
#resert_index()函數(shù):drop: 重新設置索引后是否將原索引作為新的一列并入DataFrame,默認為False
media3 = media3.reset_index(drop=True)
d = [media3.loc[i+1, 'origin_time'] < media3.loc[i, 'end_time'] for i in range(len(media3)-1)]
#df.append()可以將其他DataFrame附加到調用方的末尾,并返回一個新對象.它是最簡單、最常用的數(shù)據(jù)合并方式
d.append(False)
e = pd.Series(d)#構造一維數(shù)組
media3 = media3.loc[~e, :]#~:相反的值;d:下次觀看的開始時間小于上一次觀看的結束時間的記錄
# 5、去除小于4S的記錄:wat_time:總時長
media3 = media3.loc[media3['wat_time'] > 4, :]
# 保存貼標簽用
media3.to_csv('media3.csv', na_rep='NaN', header=True, index=False)
# 查看連續(xù)觀看同一頻道的時長是否大于3h
# 發(fā)現(xiàn)這2000個用戶不存在連續(xù)觀看大于3h的情況
media3['date'] = media3.end_time.apply(lambda x :x.date())
media_group = media3['wat_time'].groupby([media3['phone_no'],
media3['date'],
media3['station_name']]).sum()
media_group = media_group.reset_index()
media_g = media_group.loc[media_group['wat_time'] >= 10800, ]#3h=10800s
media_g['time_label'] = 1
o = pd.merge(media3, media_g, left_on=['phone_no', 'date', 'station_name'],
right_on=['phone_no', 'date', 'station_name'], how='left')
oo = o.loc[o['time_label'] == 1, :]
結果
??
?2、收費數(shù)據(jù)
對于收費數(shù)據(jù)(mmconsume-payevents),只需刪除特殊線路和政企類的用戶即可,具體步驟如下。
刪除特殊線路的用戶,用戶等級號(owner_code)為02、09、10的數(shù)據(jù)刪除政企用戶,用戶等級名稱(owner_name)為EA級、EB級、EC級、ED級、EE級的數(shù)據(jù)
代碼:
# 收費數(shù)據(jù)
#GBK編碼是中文編碼,UTF-8編碼是多字符集編碼,支持多國語言
#header:是否將原數(shù)據(jù)集中的第一行作為表頭,默認是,并將第一行作為變量名稱:如果原始數(shù)據(jù)中沒有表頭,該參數(shù)需要設置成None
# header='infer'默認以第一行作為標題, header=None不要以第一行作為標題
# sep分隔符。 csv文件的分隔符就是,可以默認。
payevents1 = pd.read_csv('mmconsume_payevents.csv', sep=',',encoding='gbk', header='infer')
#這行代碼的作用是將一個 DataFrame 中的列名重新命名為指定的列名。
#具體來說,這個 DataFrame 中包含了電話號碼、所有者姓名、事件時間、支付名稱、登錄組名稱和所有者代碼等信息,
#而這行代碼將這些列名依次改為了 phone_no、owner_name、event_time、payment_name、login_group_name 和 owner_code。
#這樣做的好處是使得數(shù)據(jù)更加易于理解和操作,可以方便地進行數(shù)據(jù)分析和處理。
#t_aa63affcd82ddfe013a1984425829dd740d86fc4_10003630_0_1.phone_no:原列名
payevents1.columns = ['phone_no', 'owner_name', 'event_time', 'payment_name',
'login_group_name', 'owner_code']#相當于重命名
# 過濾特殊線路、政企用戶
payevents2 = payevents1.loc[(payevents1.owner_code != 2
)&(payevents1.owner_code != 9
)&(payevents1.owner_code != 10), :] # 去除特殊線路數(shù)據(jù)
print('查看過濾后的特殊線路的用戶:', payevents2.owner_code.unique())
payevents3 = payevents2.loc[(payevents2.owner_name != 'EA級'
)&(payevents2.owner_name != 'EB級'
)&(payevents2.owner_name != 'EC級'
)&(payevents2.owner_name != 'ED級'
)&(payevents2.owner_name != 'EE級'), :]
print('查看過濾后的政企用戶:', payevents3.owner_name.unique())
payevents3.to_csv('payevents3.csv', na_rep='NaN', header=True, index=False)
?結果:
?
繪制可視化圖片?
matplotlib:繪制代碼
# 代碼6-4
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
import seaborn as sns
import re
plt.rcParams['font.sans-serif'] = ['SimHei'] # 設置字體為SimHei顯示中文
plt.rcParams['axes.unicode_minus'] = False # 設置正常顯示符號
media3 = pd.read_csv('media3.csv', header='infer')
# 用戶觀看總時長
m = pd.DataFrame(media3['wat_time'].groupby([media3['phone_no']]).sum())
m = m.sort_values(['wat_time'])
m = m.reset_index()
m['wat_time'] = m['wat_time'] / 3600
m['id'] = m.index
ax = sns.barplot(x='id', y='wat_time', data=m)
ax.xaxis.set_major_locator(ticker.MultipleLocator(250))
ax.xaxis.set_major_formatter(ticker.ScalarFormatter())
plt.xlabel('觀看用戶(排序后)')
plt.ylabel('觀看時長(小時)')
plt.title('用戶觀看總時長')
plt.show()
# 代碼6-5
# 所有收視頻道名稱的觀看時長與觀看次數(shù)
media3.station_name.unique()
pindao = pd.DataFrame(media3['wat_time'].groupby([media3.station_name]).sum())
pindao = pindao.sort_values(['wat_time'])
pindao = pindao.reset_index()
pindao['wat_time'] = pindao['wat_time'] / 3600
pindao_n = media3['station_name'].value_counts()
pindao_n = pindao_n.reset_index()
pindao_n.columns = ['station_name', 'counts']
a = pd.merge(pindao, pindao_n, left_on='station_name', right_on ='station_name', how='left')
fig, ax1 = plt.subplots()
ax2 = ax1.twinx() # 構建雙軸
sns.barplot(a.index, a.iloc[:, 1], ax=ax1)
sns.lineplot(a.index, a.iloc[:, 2], ax=ax2, color='r')
ax1.set_ylabel('觀看時長(小時)')
ax2.set_ylabel('觀看次數(shù)')
ax1.set_xlabel('頻道號(排序后)')
plt.xticks([])
plt.title('所有收視頻道名稱的觀看時長與觀看次數(shù)')
plt.show()
# 收視前15頻道名稱的觀看時長,由于pindao已排序,取后15條數(shù)據(jù)
sns.barplot(x='station_name', y='wat_time', data=pindao.tail(15))
plt.xticks(rotation=45)
plt.xlabel('頻道名稱')
plt.ylabel('觀看時長(小時)')
plt.title('收視前15的頻道名稱')
plt.show()
# 代碼6-6
# 工作日與周末的觀看時長比例
ind = [re.search('星期六|星期日', str(i)) != None for i in media3['星期']]
freeday = media3.loc[ind, :]
workday = media3.loc[[ind[i]==False for i in range(len(ind))], :]
m1 = pd.DataFrame(freeday['wat_time'].groupby([freeday['phone_no']]).sum())
m1 = m1.sort_values(['wat_time'])
m1 = m1.reset_index()
m1['wat_time'] = m1['wat_time'] / 3600
m2 = pd.DataFrame(workday['wat_time'].groupby([workday['phone_no']]).sum())
m2 = m2.sort_values(['wat_time'])
m2 = m2.reset_index()
m2['wat_time'] = m2['wat_time'] / 3600
w = sum(m2['wat_time']) / 5
f = sum(m1['wat_time']) / 2
plt.figure(figsize=(8, 8))
plt.subplot(211) # 參數(shù)為:行,列,第幾項 subplot(numRows, numCols, plotNum)
colors = 'lightgreen','lightcoral'
plt.pie([w, f], labels = ['工作日', '周末'], colors=colors, shadow=True,
autopct='%1.1f%%', pctdistance=1.23)
plt.title('周末與工作日觀看時長占比')
plt.subplot(223)
ax1 = sns.barplot(m1.index, m1.iloc[:, 1])
# 設置坐標刻度
ax1.xaxis.set_major_locator(ticker.MultipleLocator(250))
ax1.xaxis.set_major_formatter(ticker.ScalarFormatter())
plt.xlabel('觀看用戶(排序后)')
plt.ylabel('觀看時長(小時)')
plt.title('周末用戶觀看總時長')
plt.subplot(224)
ax2 = sns.barplot(m2.index, m2.iloc[:, 1])
# 設置坐標刻度
ax2.xaxis.set_major_locator(ticker.MultipleLocator(250))
ax2.xaxis.set_major_formatter(ticker.ScalarFormatter())
plt.xlabel('觀看用戶(排序后)')
plt.ylabel('觀看時長(小時)')
plt.title('工作日用戶觀看總時長')
plt.show()
# 代碼6-7
# 周觀看時長分布
n = pd.DataFrame(media3['wat_time'].groupby([media3['星期']]).sum())
n = n.reset_index()
n = n.loc[[0, 2, 1, 5, 3, 4, 6], :]
n['wat_time'] = n['wat_time'] / 3600
plt.figure(figsize=(8, 4))
sns.lineplot(x='星期', y='wat_time', data=n)
plt.xlabel('星期')
plt.ylabel('觀看時長(小時)')
plt.title('周觀看時長分布')
plt.show()
# 付費頻道與點播回看的周觀看時長分布
media_res = media3.loc[media3['res_type'] == 1, :]
ffpd_ind = [re.search('付費', str(i)) != None for i in media3.loc[:, 'station_name']]
media_ffpd = media3.loc[ffpd_ind, :]
z = pd.concat([media_res, media_ffpd], axis=0)
z = z['wat_time'].groupby(z['星期']).sum()
z = z.reset_index()
z = z.loc[[0, 2, 1, 5, 3, 4, 6], :]
z['wat_time'] = z['wat_time'] / 3600
plt.figure(figsize=(8, 4))
sns.lineplot(x='星期', y='wat_time', data=z)
plt.xlabel('星期')
plt.ylabel('觀看時長(小時)')
plt.title('付費頻道與點播回看的周觀看時長分布')
plt.show()
# 代碼6-8
# 設置Matplotlib正常顯示中文和負號
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
# 讀取csv文件
pay = pd.read_csv('payevents2.csv')
sns.countplot(x='payment_name', data=pay)
plt.xticks(rotation=80)
plt.xlabel('支付方式')
plt.ylabel('總數(shù)')
plt.title('用戶支付方式總數(shù)對比')
plt.show()
繪制可視化圖形
1、根據(jù)讀取與處理廣播電視數(shù)據(jù)只能簡單的對數(shù)據(jù)進行了解,并不能明確的看出數(shù)據(jù)中蘊含的信息
2、因此,需要對清洗后的數(shù)據(jù)進行可視化分析,清晰的展示出廣播電視數(shù)據(jù)中用戶的觀看信息,為運營商決策提供一定的參考
繪制用戶分析圖
分布分析是用戶在特定指標下的頻次、總額等的歸類展現(xiàn),它可以展現(xiàn)出單個用戶對產品(電視)的依賴程度,從而分析出客戶觀看電視的總時長、所購買不同類型的產品數(shù)量等情況,幫助運營人員了解用戶的當前狀態(tài)。如觀看時長(20小時以下、20小時~50小時、50小時以上等區(qū)間)等分布情況三網融合讓人們可以便捷的獲取新聞資訊,各種平臺終端更是觸手可及,同時工作節(jié)奏的加快,忙碌的人們是否還花時間訂購收看廣電節(jié)目?因此需要探索用戶的觀看總時長分布情況。計算所有用戶在一個月內的觀看總時長并且排序,從而對用戶觀看總時長分布進行可視化分布。
import pandas as pd
import pyecharts.options as opts
from pyecharts.charts import Bar
media3 = pd.read_csv('media3.csv', header='infer')
#數(shù)據(jù)處理
media3_sum = media3['wat_time'].groupby([media3['phone_no']]).sum()
m = pd.DataFrame({'phone_no': media3_sum.index, 'wat_time': media3_sum.values})
m = m.sort_values(['wat_time'])
m['wat_time'] = m['wat_time'] / 3600
m['id'] = m.index
#繪圖
bar = (
Bar()
.add_xaxis(m['id'].tolist())
.add_yaxis('觀看時長', m['wat_time'].tolist())
.set_global_opts(
xaxis_opts=opts.AxisOpts(
axislabel_opts=opts.LabelOpts(formatter='{value}'),
name='觀看時長',
name_location='center',
name_gap=50
),
yaxis_opts=opts.AxisOpts(
axislabel_opts=opts.LabelOpts(formatter='{value}小時'),
name='用戶數(shù)',
name_location='center',
name_gap=30
),
title_opts=opts.TitleOpts(title='用戶觀看總時長'))
.set_series_opts(
label_opts=opts.LabelOpts(position='top', formatter='{c}小時',is_show=False)
)
)
bar.render("1.html")
?
?
繪制頻道分析圖
貢獻度分析又稱帕累托分析,它的原理是帕累托法則又稱20/80定律。同樣的投入放在不同的地方會產生不同的效益。例如,對一個公司而言,80%的利潤常來自于20%最暢銷的產品,而其他80%的產品只產生了20%的利潤。為更好的了解觀眾最熱衷哪些節(jié)目或哪些頻道最受歡迎,提高收視率,因此需要對所有收視頻道名稱的觀看時長與觀看次數(shù)進行貢獻度分析。
??
?
?
繪制時長分析圖
對比分析是指將兩個相互聯(lián)系的指標進行比較,從數(shù)量上展示和說明研究對象規(guī)模的大小、水平的高低、速度的快慢和各種關系是否協(xié)調,特別適用于指標間的橫縱向比較、時間序列的比較分析。在對比分析中,選擇合適的對比標準是十分關鍵的步驟。當選擇合適的對比標準時,才能做出客觀的評價;當選擇不合適的對比標準時,評價可能得出錯誤的結論。對比分析主要有兩種形式:靜態(tài)對比和動態(tài)對比。靜態(tài)對比,是指在同一時間條件下對不同總體指標進行比較,如不同部門、不同地區(qū)、不同國家的比較,也稱為“橫比”;動態(tài)對比,是指在同一總體條件下對不同時期指標數(shù)據(jù)的比較,也稱為“縱比”。將工作日(5天)與周末(2天)進行劃分,使用餅圖展示所有用戶的觀看總時長的占比分布(計算觀看總時長時需要除以天數(shù)),并對所有用戶在工作日和周末的觀看總時長的分布使用柱狀圖進行對比。
?
?
繪制周時長分析圖
為了使運營商清楚的了解在一周時間內每天的觀看時長,從而有針對性的投放受歡迎的節(jié)目,增加用戶的使用黏度。需要分別繪制了頻道周觀看時長分布圖以及付費頻道與點播回看的周觀看時長分布圖。?
?
繪制用戶支付方式分析圖
傳統(tǒng)廣播電視企業(yè)如果在互聯(lián)網時代脫穎而出,那么不僅要在電視節(jié)目以及電視節(jié)目投放安排上進行分析,還要開發(fā)一些產品的周邊服務,為用戶帶來全新的體驗。通過繪制用戶支付方式分析圖,觀察用戶的支付方式情況,從而方便傳統(tǒng)廣播電視企業(yè)為用戶開展一些便民服務,吸引更多的用戶使用,增加收益。?
項目分析報告?
通過對收視行為信息數(shù)據(jù)和收費數(shù)據(jù)的進行清洗和可視化分析,已經初觀察出用戶的觀看時長走勢分布、收視頻道的排名、工作日與周末收視觀看占比、點播回看的總體情況以及用戶付費方式。了解更清晰的展示項目的結果,需要撰寫項目分析報告,幫助開發(fā)者掌握廣電大數(shù)據(jù)可視化的項目分析結果,給決策部門提供一個完整規(guī)范的方案,并幫助企業(yè)靈活調整經營決策。分析報告包括了背景與目的、分析思路、分析結果、總結與建議,其模板如第一章撰寫項目分析報告示例圖所示。由于前面已經介紹過本項目的背景與目的,所以此處將不再重復介紹。
背景與目的
新零售智能銷售設備以線上經營的理念,
了解銷售的整體情況,為新零售智能銷售設備商家提供相關的建議。
分析思路
收集大數(shù)據(jù)平臺上的數(shù)據(jù)進行讀取,清楚的熟悉數(shù)據(jù)的結構根據(jù)項目的分析目的對收集到的數(shù)據(jù)進行清洗,包括對收視行為信息數(shù)據(jù)、賬單與收費數(shù)據(jù)、訂單數(shù)據(jù)和用戶狀態(tài)數(shù)據(jù)進行清洗處理根據(jù)清洗后數(shù)據(jù)進行可視化分析,包括用戶分析、頻道分析、時長分析、周時長分析和用戶支付方式分析
?
分析結果
由圖可知,大部分用戶的觀看總時長主要集中在100小時~400小時之間。且隨著收視用戶的增多,電視節(jié)目的觀看時長也在穩(wěn)步增長。一個月平均每天觀看10小時左右,這說明用戶對廣電節(jié)目有一定的依賴性,同時也說明了廣電節(jié)目對用戶有一定的吸引力,但仍然有一定的增長空間。
?
分析結果
由圖可知,隨著觀看各頻道次數(shù)增多,觀看時長也在隨之增多,且后面近28%的頻道帶來了80%的觀看時長貢獻度。出現(xiàn)這種情況的原因可能是也部分頻道具有地方特色,或播放的節(jié)目比較受歡迎。
?
由圖可知,排名前15的頻道名稱為翡翠臺、中央3臺、中央新聞、廣東體育、中央8臺、CCTV5+體育賽事、廣東珠江、廣東南方衛(wèi)視、江蘇衛(wèi)視、中央6臺、鳳凰中文、中央4臺、廣州電視、中央1臺、中央5臺。其中,廣東體育、廣東珠江、廣東南方衛(wèi)視、廣州電視都相對具有地方特色,而翡翠臺則是廣東話(粵語)廣播為主的綜合娛樂頻道,也相對符合廣東人民的喜好。同時這也從側面證明了所有收視頻道名稱的觀看時長與觀看次數(shù)圖的分析結果。
?
由圖可知,周末的觀看時長占觀看總時長的52.5%,而工作日的觀看時長的占比為47.5%;周末觀看的用戶時長集中在20小時~100小時之間,工作日觀看的用戶時長集中在50小時~250小時之間。雖然在比例圖中,周末與工作日的比例相差不大,但是在分布圖中工作日的觀看總時長仍比周末的觀看總時長多,并且兩者分布圖形狀相似。出現(xiàn)這種情況的原因可能是因為周末用戶可支配的時間更多,有更多的時間可用于觀看電視節(jié)目。但是周末只有2天,工作日有5天,所以工作日的觀看總時長會比周末的觀看總時長多。
?
由以下兩圖可知,在一周中,周一、周六、周日的觀看時間較長,其中周日觀看時間最長。這說明人們更喜歡在周末且傾向于付費觀看,在周二到周五忙于工作,無暇顧及電視節(jié)目,可能在周末點播回看。?
由圖可知,大多數(shù)用戶選擇現(xiàn)金支付,其次是翼支付托收、人行托收,選擇網廳網銀、短信支付、支付寶、支票、建行龍支付、微信等方式的用戶極少。說明用戶還是受傳統(tǒng)思想影響,傾向于使用現(xiàn)金支付,但是現(xiàn)金攜帶不便,也帶來一定的安全隱患。同時加強宣傳,引導用戶選擇掌上支付,業(yè)務也加強集成,方便終端綁定,一鍵式便捷支付。
?
總結與建議
通過對廣電大數(shù)據(jù)可視化分析,提出以下總結與建議。
大部分用戶的觀看總時長主要集中在100小時~300小時之間且隨著用戶觀看各頻道次數(shù)增多,觀看時長也在隨之增多。因此,可以適當?shù)母牟煌l道的節(jié)目單,添加頻道的吸引力,從而增多用戶觀看各頻道次數(shù)和時長。用戶觀看時長前15名的頻道分別為翡翠臺、中央3臺、中央新聞、廣東體育、中央8臺、CCTV5+體育賽事、廣東珠江、廣東南方衛(wèi)視、江蘇衛(wèi)視、中央6臺、鳳凰中文、中央4臺、廣州電視、中央1臺、中央5臺。針對這個現(xiàn)象,并且周末的觀看時長略高于工作日。針對這個現(xiàn)象,經營者可以在用戶觀看時長前15名的頻道中將用戶喜好的節(jié)目投放時間把控在周末進行播放,從而提高用戶的觀看興趣,增加用戶黏度。從而增加收視率。大多數(shù)用戶選擇現(xiàn)金支付。針對這個現(xiàn)象,經營者可以加大線上繳費服務推廣宣傳,吸引更多的用戶,付費頻道可以在周日提供更多的節(jié)目吸引用戶消費,增加收益。
?
小結
?本章基于廣播電視數(shù)據(jù),包括用戶的收視行為信息數(shù)據(jù)和收費數(shù)據(jù),介紹了數(shù)據(jù)清洗的方法。并從用戶分析、頻道分析、時長分析、周時長分析和用戶支付方式分析5個方面對廣播電視數(shù)據(jù)進行可視化分析。從而根據(jù)可視化結果,撰寫項目分析報告。
?
?
?
柚子快報激活碼778899分享:數(shù)據(jù)可視化之廣電大數(shù)據(jù)
精彩文章
本文內容根據(jù)網絡資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點和立場。
轉載請注明,如有侵權,聯(lián)系刪除。