【DataFrame常用操作】以影院票房日度數(shù)據(jù)為例

王校長吃熱狗

在處理數(shù)據(jù)的過程中笛丙,經常用到強大的Pandas.DataFrame宋税,由于其參數(shù)多自由度高,有時候容易暈頭轉向一睁。
故將數(shù)據(jù)清洗宗苍、處理和畫圖中的常用操作總結如下稼稿。
不定期更新,歡迎收藏讳窟。

這次利用tushare提供的影院日度票房數(shù)據(jù)接口為例進行演示让歼。


bo_cinema接口介紹

為什么要放王校長吃熱狗的圖?答案在文中丽啡。
(1)準備工作
加載需要的庫:

# -*- coding: UTF-8 -*-
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import tushare as ts
from datetime import datetime
import time
import pylab

注冊tushare獲得‘your token’:

%matplotlib inline
pro = ts.pro_api('your token')
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus']=False
df = pd.DataFrame()

設定jupyter notebook中顯示圖片的尺寸:

pylab.rcParams['figure.figsize'] = (8, 4.5)

(2)獲取數(shù)據(jù)

def get_data(df, startdate, enddate):
    # 日期格式轉換
    tp = [x.strftime('%Y%m%d') for x in list(pd.date_range(start=startdate, end=enddate))]
    print(tp)
    for t in tp:
        #加個延遲避免被ban
        time.sleep(62/40)
        dfdaily = pro.bo_cinema(date = t)
        df = pd.concat([df, dfdaily], axis=0) # 縱向合并
    return df


startdate = '20190205'
enddate = '20190321'
data = get_data(df, startdate, enddate)

輸出的日期列表:

    ['20190205', '20190206', '20190207', '20190208', '20190209', '20190210', '20190211', '20190212', '20190213', '20190214', '20190215', '20190216', '20190217', '20190218', '20190219', '20190220', '20190221', '20190222', '20190223', '20190224', '20190225', '20190226', '20190227', '20190228', '20190301', '20190302', '20190303', '20190304', '20190305', '20190306', '20190307', '20190308', '20190309', '20190310', '20190311', '20190312', '20190313', '20190314', '20190315', '20190316', '20190317', '20190318', '20190319', '20190320', '20190321']

查看原始數(shù)據(jù)前5行:

data.head()
查看原始數(shù)據(jù)前5行

說明:該數(shù)據(jù)是按每日票房收入(day_amount)對全國影院進行排名谋右,列出全國排名前100的影院(看看有你去過的沒)。
查看data的形狀:

data.shape
(3900, 9)

描述性統(tǒng)計:

data.describe().T
描述性統(tǒng)計

(3)進行初步分析
按影院上榜次數(shù)計數(shù):

c_name_conunts = data['c_name'].value_counts()
c_name_conunts[:30]

輸出前30家:
(看看有你去過的嗎~)

金逸北京薈聚IMAX店        39
廣州飛揚影城(正佳分店)       39
首都電影院西單店           39
武漢漢街萬達廣場店          39
UME影城(北京雙井店)       39
蘭州城關萬達廣場店          39
武商摩爾國際電影城          39
中影國際影城珠海華發(fā)2店       39
Jackie Chan北京耀萊    39
南京新街口國際影城          38
金逸北京大悅城IMAX店       38
蘭州中心空間站IMAX影城      38
北京通州萬達廣場店          37
北京市金泉港國際影城         37
廣州市捷登都會飛揚影城        36
金逸天津大悅城IMAX店       36
成都錦華萬達廣場店          36
南昌紅谷灘萬達廣場店         35
昆明萬達影城同德廣場店        35
廣州飛揚影城             35
首都電影院昌平店           35
深圳市百老匯電影中心影城       34
盧米埃北京長楹天街IMAX影城    34
金逸上海龍之夢IMAX店       33
大連經開萬達廣場店          33
金逸廣州海珠城IMAX店       33
中影國際影城北京昌平永旺店      33
中影國際影城武漢光谷天河店      32
福州倉山萬達廣場店          32
UME影城(重慶渝中店)       31
Name: c_name, dtype: int64

畫簡單的橫柱狀圖:

c_name_conunts[:15].plot(kind='barh', rot=0)
output_9_1.png

按影院名稱是否含“萬達”進行分類补箍,研究萬達相關影院的情況:
(強行解釋題圖)

if_wanda = np.where(data.c_name.str.contains('萬達'), 'Wanda', 'Not Wanda')
if_wanda[:5]

查看:

array(['Not Wanda', 'Not Wanda', 'Not Wanda', 'Wanda', 'Not Wanda'], dtype='<U9')

想要直接按萬達和非萬達分組進行與上面類似的計數(shù)會有些復雜改执,這里提供pandas之父麥金尼的方法啸蜜,創(chuàng)造性的用df.groupby()和.size().unstack()解決:

by_cname_ifwanda = data.groupby(['rank', if_wanda])
agg_counts = by_cname_ifwanda.size().unstack().fillna(0)
agg_counts[:10]

效果如下:


按是否萬達分組計數(shù)

在萬達的電影院,每日排名一般在多少位呢辈挂?
畫出能體現(xiàn)萬達比例的柱形圖衬横,可視性更好:

agg_counts[:25].plot(kind='barh', stacked=True)
output_12_1.png

畫折線圖:

plt.plot(agg_counts['Not Wanda'], label='Not Wanda', linestyle='--')
plt.plot(agg_counts.Wanda, label='Wanda')
plt.plot((0, 100), (18.5, 18.5), color='black', lw =0.5)
plt.legend()

output_13_1.png

(4)用透視表分析
將if_wanda添加到原始數(shù)據(jù)中形成新的列(即df增加columns),并查看:

data['ifwanda'] = if_wanda
data.head()
新增一列

考察同樣排名情況下呢岗,萬達與非萬達的平均票價差距:

mean_stat = data.pivot_table('avg_price', index='rank', columns='ifwanda', aggfunc='mean')
mean_stat['diff']=mean_stat['Wanda']-mean_stat['Not Wanda']
mean_stat[:20].round(2)
相同排名時平均票價差距

畫柱狀圖:

#plt.plot(mean_stat['diff'])
plt.plot((0, 100), (0, 0), color='black', lw =0.5)
plt.bar(mean_stat.index, mean_stat['diff'])
output_17_1.png

直觀上冕香,排名相同的情況下,萬達的影院要比非萬達影院平均票價貴后豫。
求平均票價差距的均值:

mean_stat['diff'].mean()
 3.4035306779919057

即平均貴3.40元悉尾。
接下來,從總體角度分析挫酿。
創(chuàng)建一個新的數(shù)據(jù)集构眯,只保留想研究的3個columns:
(通過字典創(chuàng)建)

sum_datadic = {'date': data.date,
               'day_amount': data.day_amount,
               'att_ratio': data.att_ratio,
               'avg_price': data.avg_price}
sum_data = pd.DataFrame(sum_datadic)
sum_data[:10]
sum_data

日常中面板數(shù)據(jù)比較常用的,按日期求均值:
(注意pivot_table的用法)

mean2 = data.pivot_table(['att_ratio', 'day_amount', 'avg_price'], index='date', aggfunc='mean')
mean2.day_amount = mean2.day_amount/10000
mean2[:10].round(2)
mean2

研究新數(shù)據(jù)集3列間的關系早龟,
畫折線圖:

timeline = [datetime.strptime(d, '%Y%m%d').date() for d in mean2.index]
plt.plot(timeline, mean2.att_ratio, label='日均上座率(%)', linestyle=':')
plt.plot(timeline, mean2.day_amount, label='日均單影院收入(萬元)',linestyle='--')
plt.plot(timeline, mean2.avg_price, label='日均票價(元)')
plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%m-%d'))
plt.legend(loc='best')
plt.grid()
上座率和收入呈現(xiàn)明顯周末效應惫霸,票價雖有波動但不如前兩者明顯〈械埽考慮到定價受多方面因素掣肘壹店,影院想提高收入還得從提高上座率入手。

另一種方法:直接對原始數(shù)據(jù)按日平均

data_by_day = data.pivot_table(data.columns, index='date', aggfunc='mean')
data_by_day.round(2)[:10]
少了一行

結果發(fā)現(xiàn)少了一行(aud_count)芝加,原因是該列數(shù)據(jù)的類型不是整數(shù)型或浮點型硅卢,不能計算。
類型轉換就可以了:

data.aud_count = data.aud_count.astype('int')
data_by_day = data.pivot_table(data.columns, index='date', aggfunc='mean')
data_by_day.round(2)[:10]
重新構造透視表

將data_by_day中的6列數(shù)據(jù)用折線圖表示出來藏杖,
畫多個子圖:

fig, axs = plt.subplots(6, 1)
j=0
timeline = [datetime.strptime(d, '%Y%m%d').date() for d in data_by_day.index]
for col in data_by_day.columns:
    axs[j].plot(timeline, data_by_day[col])
    axs[j].xaxis.set_major_formatter(mdates.DateFormatter('%m%d'))
    #axs[j].xaxis.set_major_locator(mdates.MonthLocator())
    axs[j].set(title=col)
    axs[j].grid()
    j += 1
plt.tight_layout()
#plt.gcf().autofmt_xdate()
畫多個子圖

發(fā)現(xiàn)圖像在jupyter notebook里顯示的太過細小了将塑,通過下面的語句調整顯示圖片的尺寸;

pylab.rcParams['figure.figsize'] = (8, 16)

重新畫圖:

fig, axs = plt.subplots(6, 1)
j=0
timeline = [datetime.strptime(d, '%Y%m%d').date() for d in data_by_day.index]
for col in data_by_day.columns:
    axs[j].plot(timeline, data_by_day[col])
    axs[j].xaxis.set_major_formatter(mdates.DateFormatter('%m%d'))
    #axs[j].xaxis.set_major_locator(mdates.MonthLocator())
    axs[j].set(title=col)
    axs[j].grid()
    j += 1
plt.tight_layout()
#plt.gcf().autofmt_xdate()
效果好多了

(本文基于偉大的麥金尼所著《利用python進行數(shù)據(jù)分析》和本人粗淺的日常經驗蝌麸。)

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末点寥,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子来吩,更是在濱河造成了極大的恐慌敢辩,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件弟疆,死亡現(xiàn)場離奇詭異责鳍,居然都是意外死亡,警方通過查閱死者的電腦和手機兽间,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來正塌,“玉大人嘀略,你說我怎么就攤上這事恤溶。” “怎么了帜羊?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵咒程,是天一觀的道長。 經常有香客問我讼育,道長帐姻,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任奶段,我火速辦了婚禮饥瓷,結果婚禮上,老公的妹妹穿的比我還像新娘痹籍。我一直安慰自己呢铆,他們只是感情好,可當我...
    茶點故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布蹲缠。 她就那樣靜靜地躺著棺克,像睡著了一般。 火紅的嫁衣襯著肌膚如雪线定。 梳的紋絲不亂的頭發(fā)上娜谊,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天,我揣著相機與錄音斤讥,去河邊找鬼纱皆。 笑死,一個胖子當著我的面吹牛周偎,可吹牛的內容都是我干的抹剩。 我是一名探鬼主播,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼蓉坎,長吁一口氣:“原來是場噩夢啊……” “哼澳眷!你這毒婦竟也來了?” 一聲冷哼從身側響起蛉艾,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤钳踊,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后勿侯,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體拓瞪,經...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年助琐,在試婚紗的時候發(fā)現(xiàn)自己被綠了祭埂。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖蛆橡,靈堂內的尸體忽然破棺而出舌界,到底是詐尸還是另有隱情,我是刑警寧澤泰演,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布呻拌,位于F島的核電站,受9級特大地震影響睦焕,放射性物質發(fā)生泄漏藐握。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一垃喊、第九天 我趴在偏房一處隱蔽的房頂上張望猾普。 院中可真熱鬧,春花似錦缔御、人聲如沸抬闷。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽笤成。三九已至,卻和暖如春眷茁,著一層夾襖步出監(jiān)牢的瞬間炕泳,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工上祈, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留培遵,地道東北人。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓登刺,卻偏偏與公主長得像籽腕,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子纸俭,可洞房花燭夜當晚...
    茶點故事閱讀 42,877評論 2 345