python熊猫弹幕_Pandas+Matplotlib:视频弹幕统计分析
彈幕[dàn mù] (danmaku),中文流行詞語(yǔ),指的是在網(wǎng)絡(luò)上觀看視頻時(shí)彈出的評(píng)論性字幕。源自日本彈幕視頻分享網(wǎng)站(niconico動(dòng)畫),國(guó)內(nèi)首先引進(jìn)為Acfun以及后來(lái)的嗶哩嗶哩網(wǎng)站。
大量吐槽評(píng)論從屏幕飄過(guò)時(shí)效果看上去像是飛行射擊游戲里的彈幕,所以NICO網(wǎng)民將這種有大量的吐槽評(píng)論出現(xiàn)時(shí)的效果做彈幕。
在中國(guó),本來(lái)只有大量評(píng)論同時(shí)出現(xiàn)才能叫彈幕,但是隨著誤用單條評(píng)論也能叫彈幕了。
想法:彈幕量與視頻中的高曝光片段出現(xiàn)時(shí)間段是否有關(guān)?彈幕量與自然時(shí)間之間是否有一定關(guān)聯(lián)性?
數(shù)據(jù):從嗶哩嗶哩網(wǎng)站上爬下來(lái)的彈幕數(shù)據(jù)
分析過(guò)程:爬下來(lái)的Excel數(shù)據(jù)文件,里面是啥樣的?數(shù)據(jù)是否完整?如何通過(guò)視頻時(shí)間和自然時(shí)間分別統(tǒng)計(jì)彈幕量?如何以可視化的形式表達(dá)?
上述就是整個(gè)分析流程,下面開(kāi)始一步步進(jìn)行
任務(wù)一:對(duì)于 '熱點(diǎn)事件.xlsx' 文件的Sheet3表單而言,需要統(tǒng)計(jì)視頻時(shí)間中每秒內(nèi)彈幕的數(shù)量并可視化展示
import pandas as pd
import matplotlib.pyplot as plt
①讀入數(shù)據(jù)
fpath = './datas/熱點(diǎn)事件.xlsx'
df = pd.read_excel(fpath,sheet_name='Sheet3')
這里,我已知分析所用數(shù)據(jù)在Sheet3表單中,所以直接調(diào)用了。
其實(shí)在不知情的情況下,應(yīng)該先對(duì)Excel文件進(jìn)行“結(jié)構(gòu)性”讀取(自己理解的)。
如何“結(jié)構(gòu)性”讀取,在后面會(huì)用到。
②查看數(shù)據(jù)的“樣子”
df.head()
一看,有用的就前兩列,第一列是彈幕發(fā)送的視頻時(shí)間,第二列是數(shù)量。
df.shape # 結(jié)果為(1048575, 6)
好大的數(shù)據(jù)量啊,有問(wèn)題!EXCEL表格文件最多就只有1048575行。
df.dropna(axis="index", how='all', inplace=True)
先刪除全部為空值的行試試。
df.shape # 結(jié)果為(501, 6)
這里一看,好家伙,全是空值.....還好進(jìn)行了空值處理。最終需要處理的總共501行數(shù)據(jù)。
其實(shí)這里回頭想,少了一步,我們看了開(kāi)頭的五行數(shù)據(jù),其實(shí)也可以看看結(jié)尾的五行數(shù)據(jù)是啥樣子的。
后面重新做的時(shí)候我發(fā)現(xiàn),在原始表格第1048575行的數(shù)據(jù)是統(tǒng)計(jì)了有多少行數(shù)據(jù)= =|||,這里應(yīng)該是人為操作失誤。
③按照視頻時(shí)間的每秒進(jìn)行彈幕量統(tǒng)計(jì)
df.loc[(0 <= df['時(shí)間']) & (df['時(shí)間'] < 1),'數(shù)量'].sum() # 運(yùn)行結(jié)果為8.0
由于"時(shí)間"列中均是精確到秒后三位小數(shù),這里利用df.loc進(jìn)行區(qū)域限定,然后借助"數(shù)量"列進(jìn)行求和。
這樣就統(tǒng)計(jì)出了0至1秒,也就是1秒內(nèi)的彈幕量,如法炮制,求出每秒的彈幕量。
# 基于上述方法,寫一個(gè)for循環(huán),解決戰(zhàn)斗
for i in range(501):
count = df.loc[(i <= df['時(shí)間']) & (df['時(shí)間'] < i+1),'數(shù)量'].sum()
print('第{}秒內(nèi)共有{}條彈幕'.format(i, count))
運(yùn)行結(jié)果如下圖所示。
通過(guò)上述代碼運(yùn)行結(jié)果會(huì)發(fā)現(xiàn),在109秒后出現(xiàn)的都是0條彈幕。
為啥是這樣?因?yàn)殡m然是501條,但是要計(jì)算每1秒內(nèi)的彈幕量,這樣累加之后,總行數(shù)就遠(yuǎn)遠(yuǎn)低于501行了。
這樣看來(lái),欠考慮。應(yīng)該基于最后一條彈幕的秒數(shù),給range()里面的參數(shù)賦值。
# 按照前面所想,可以看出以秒為單位的時(shí)間段最終為109.420秒
# 因此,給range()賦值110即可,為啥不是109?因?yàn)閞ange()里面是左閉右開(kāi)區(qū)間,取110意味著[0,110)
for i in range(110):
count = df.loc[(i <= df['時(shí)間']) & (df['時(shí)間'] < i+1),'數(shù)量'].sum()
print('第{}秒內(nèi)共有{}條彈幕'.format(i, count))
為啥做上述的優(yōu)化?
其實(shí)是我做到可視化部分發(fā)現(xiàn)的問(wèn)題,回過(guò)頭來(lái)在這里優(yōu)化了。
④可視化展示
# 最后用柱狀圖可視化展示
# 這里要注意plt.bar()函數(shù)默認(rèn)顏色循環(huán)使用,如果這里不指定一個(gè)顏色,柱狀圖會(huì)變得五顏六色
for i in range(110):
count = df.loc[(i <= df['時(shí)間']) & (df['時(shí)間'] < i+1),'數(shù)量'].sum()
#print('第{}秒內(nèi)共有{}條彈幕'.format(i, count))
plt.bar(i, count, color='#008B8B')
plt.show() # 這里相當(dāng)于在一塊畫布上每次畫一條柱狀圖,直到for循環(huán)結(jié)束,輸出結(jié)果
看看每5秒統(tǒng)計(jì)一次的結(jié)果。
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
# 最后,以5秒為一個(gè)間隔,看看彈幕的分布情況(有時(shí)候精細(xì)未必是好事,擴(kuò)大間隔有助于分析問(wèn)題)
for i in range(0, 110, 5):
count = df.loc[(i <= df['時(shí)間']) & (df['時(shí)間'] < i+5),'數(shù)量'].sum()
plt.bar(i, count, width=1, color='#008B8B') # 給定個(gè)寬度,出圖看的緊湊些
plt.xlabel('彈幕時(shí)間(秒)', fontsize=12)
plt.ylabel('彈幕量(條)', fontsize=12)
plt.savefig('fix11.svg', dpi=500) # 保存
plt.show() # 這里相當(dāng)于在一塊畫布上每次畫一條柱狀圖,直到for循環(huán)結(jié)束,輸出結(jié)果
從上圖上就能很明顯看出:
在視頻時(shí)間10至25秒、65至75秒、90至95秒以及最后時(shí)刻,彈幕量較為集中。
再次觀看視頻發(fā)現(xiàn),這些彈幕集中的某些視頻時(shí)間段剛好對(duì)應(yīng)視頻中的高潮片段,符合觀眾觀看行為。
任務(wù)二:對(duì)于 '熱點(diǎn)事件.xlsx' 文件的原數(shù)據(jù)表單而言,需要統(tǒng)計(jì)以自然時(shí)間每天的彈幕數(shù)量并可視化展示
這里,假設(shè)我們不清楚拿到的Excel文件內(nèi)部啥樣子,你可以這樣打開(kāi)觀察。
先看看文件中有多少個(gè)sheet(表單)。
但是按照以往讀取Excel文件,你會(huì)發(fā)現(xiàn),只能讀取到第一個(gè)表單的數(shù)據(jù)(默認(rèn)的)。
import pandas as pd
import matplotlib.pyplot as plt
file_path = './datas/熱點(diǎn)事件.xlsx'
xx = pd.read_excel(file_path)
有同學(xué)說(shuō),你可以加上表單名稱參數(shù)啊。但是剛說(shuō)過(guò)了,我們假設(shè)拿到的數(shù)據(jù),你完全不知道里面啥樣。怎么辦?
這時(shí)候可以用另一種Excel文件讀取方式:pd.ExcelFile( )
data = pd.ExcelFile(file_path)
data.sheet_names
這樣就可以將讀取Excel數(shù)據(jù)的所有表單名稱打印出來(lái)了,如下圖。
假設(shè)我需要的數(shù)據(jù)在表單名為‘原數(shù)據(jù)’中,則通過(guò)如下代碼:
df = data.parse('Sheet5')
這樣就回到了我們之前的DataFrame的操作流程上來(lái)了。
如上圖所示,又出現(xiàn)了新問(wèn)題。讀取時(shí),原文件開(kāi)始有空行,所以造成讀取后,原本的列標(biāo)簽變成了數(shù)據(jù)。這里只需要設(shè)定指定一行為索引即可,代碼如下:
df = data.parse('Sheet5', header=1)
完美解決,開(kāi)始數(shù)據(jù)分析。
①首先將第一列(日期)作為標(biāo)簽列
df = df.set_index('行標(biāo)簽') # 將“行標(biāo)簽”設(shè)置為index
這時(shí)又發(fā)現(xiàn),其中columns的值為‘以下項(xiàng)目的計(jì)數(shù):數(shù)量’,太繞口,寫起來(lái)太麻煩。
利用rename( )修改列名,以字典的形式傳入值,進(jìn)行修改,代碼如下:
df_clearn = df.rename(columns={'以下項(xiàng)目的計(jì)數(shù):數(shù)量':'counts'})
②以天為單位進(jìn)行統(tǒng)計(jì)
df_clearn.resample('d').sum()['counts']
如果只統(tǒng)計(jì)2018年全年的,可以使用如下代碼:
df_day = df_clearn.resample('d').sum()['counts']
df_2018 = df_day['2018']
③可視化展示
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
plt.figure(figsize=(10,4))
plt.plot(df_2018.index, df_2018, color='#008B8B')
plt.xlabel('自然時(shí)間(天)',fontsize=12)
plt.ylabel('彈幕量(條)',fontsize=12)
plt.savefig('picture.svg', dpi=500)
plt.show()
從上圖上就能很明顯看出:
隨著自然時(shí)間的推移,熱點(diǎn)事件的評(píng)論熱度會(huì)慢慢降低直至“冷卻”,符合常理。
今天的分享到這里就結(jié)束了,我最近收獲最大的就是拿到一個(gè)簡(jiǎn)單的實(shí)際問(wèn)題,通過(guò)自己所學(xué),查漏補(bǔ)缺,這樣進(jìn)步會(huì)很快,我還是不建議類似于A到Z的背單詞方法,其實(shí)背作文何嘗不是一種背單詞的方法呢?
哈哈,隱喻,自行理解~
END
總結(jié)
以上是生活随笔為你收集整理的python熊猫弹幕_Pandas+Matplotlib:视频弹幕统计分析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: odoo centos 安装odoo14
- 下一篇: 菜鸟对APP界面设计的一些心得小结