python數(shù)據(jù)分析告訴你ofo多久退押金

ofo是國內(nèi)共享單車模式的開創(chuàng)者,引航者。在18年之前的單車風口上一時風頭無兩,曾花費一千萬購買行星命名權,可見其財大氣粗。后來潮水褪去,ofo瘋狂燒錢擠占市場傾軋對手的策略最終擱淺,風光不再,連退押金都成了問題。

現(xiàn)如今,退押金需要排隊,很多人都已經(jīng)排到了一千多萬名的隊伍。我爬取了某用戶數(shù)天內(nèi)的排名變化情況,進而推測到底該用戶何時才能拿到押金。
數(shù)據(jù)集大致如圖1所示。


圖1

該數(shù)據(jù)集一共有兩列,163行。記錄了從2019/3/16-2019/3/22這七天的排名變化情況。先利用該數(shù)據(jù)集畫一個最簡單的散點圖,觀察大致的數(shù)據(jù)情況。

import pandas as pd
from pandas import DataFrame,Series
from dateutil import parser
from matplotlib import pyplot as plt
data = pd.read_csv('ofo.csv')
times = []
for i in range(len(data.loc[:,'time'])):                       
    data.loc[i,'time'] = parser.parse(data.loc[i,'time'])#將每個字符串類型轉換為時間類型
print(data)                                  #輸出data觀察數(shù)據(jù)
plt.plot_date(data['time'],data['rank'])
plt.savefig('散點圖.png', bbox_inches='tight')    #保存圖片并去掉周圍空白
plt.xticks(rotation=45)                        #旋轉橫坐標
plt.show()

效果如圖2所示。


圖2

可以看出雖然該數(shù)據(jù)集時間范圍包含了七天,可是從20號開始點才比較密集,因此縮小時間范圍,重新觀察。通過9.2圖,發(fā)現(xiàn)22號的點最密集,覆蓋時間范圍也最完整,因此把時間范圍縮減到22號這一點繼續(xù)進行分析。

#引入包
import pandas as pd
from pandas import DataFrame,Series
from dateutil import parser
from matplotlib import pyplot as plt
data = pd.read_csv('ofo.csv')
times = []
for i in range(len(data.loc[:,'time'])):
    data.loc[i,'time'] = parser.parse(data.loc[i,'time'])
data.set_index(['time'],inplace=True)           #把時間列變?yōu)樗饕?ofo = data['2019-03-22']                      #利用時間索引類型切片22號這天的時間序列
ofo['time'] = ofo.index                        #再將索引變?yōu)榱?plt.plot_date(ofo['time'],ofo['rank'])             #繪制散點圖
plt.savefig('散點圖.png', bbox_inches='tight')    #保存圖片并去掉周圍空白
plt.xticks(rotation=45)                        #旋轉橫坐標
plt.show()

這里要提及一下代碼邏輯。第一步通過循環(huán)把每個類型為字符串的時間點變?yōu)闀r間類型,然后把存有該類型的列變?yōu)樗饕5诙酵ㄟ^索引提取時間序列切片。第三步再把索引變回列。最后第四步使用plot_date函數(shù)繪制散點圖。

為什么這么麻煩?兜了一個圈子把時間這列變來變?nèi)?。首先,只有當索引為時間類型時才可以如此切片,即直接傳入’2019-03-22’就可以得到時間范圍是該天的時間序列。其次,繪制散點圖不可以用Series,只可以使用Dataframe。如果把時間列當為索引,該數(shù)據(jù)類型只有一列rank,就變成了Series。所以要把時間列再變回去,成為Dataframe才可以。

還有要注意一點的是,當使用傳統(tǒng)的scatter函數(shù)時繪制散點圖會失敗。這是因為該函數(shù)繪制散點圖時只接受x軸為數(shù)字。這里需要使用plot_date函數(shù),該函數(shù)專門應對繪制時間序列的散點圖。

代碼效果如圖3所示。


圖3

從該圖中可以大致發(fā)現(xiàn)一些規(guī)律。在22號這天,早上十點之前,晚上八點以后,排名是沒有變化的,推測這應該是ofo的下班時間。(一天工作10個小時,還算可以了,哈哈)然后在工作時間內(nèi),基本隨著時間呈線性下降趨勢。所以進一步研究,截取10:00-20:00這段時間來觀察。
代碼基本同上,做如下改動即可:

ofo = data['2019-03-22 10:00':'2019-03-22 20:00']

效果如圖4所示。


圖4

通過這張圖以及結合原始數(shù)據(jù)集可知,ofo界面每五分鐘刷新一次,更改一次退押金排隊位置??梢源笾驴闯觯惶靸?nèi)十個小時,rank的變化速率比較均勻,基本是在勻速降低。接下來,具體求解到底這個速率是多少。

引入包上面已經(jīng)給出

data = pd.read_csv('ofo.csv')
times = []
for i in range(len(data.loc[:,'time'])):
    data.loc[i,'time'] = parser.parse(data.loc[i,'time'])
data.set_index(['time'],inplace=True)
ofo = data['2019-03-22 10:00':'2019-03-22 20:00']
ofo_shift = ofo.shift(1)                            #滯后,方便后面進行減法運算
ofo_speed_rank = ofo_shift – ofo                #兩個Series相減
ofo_speed_rank.plot()
plt.show()

通過shift函數(shù)實現(xiàn)時間序列的滯后(函數(shù)參數(shù)正為滯后,負為超前),方便了之后兩個Series之間相減,然后繪制簡單的折線圖,觀察每五分鐘,排名變化情況。
效果如圖5所示。


image.png

結合圖4可以發(fā)現(xiàn)如下幾個問題。
一、有幾個時間段沒有數(shù)據(jù)(數(shù)據(jù)缺失),造成中間間隔較大,并不是每五分鐘都有數(shù)據(jù)的。二、有幾個時間點速率為0,這是由于間隔點太密集造成排名無變化造成的。通過折線圖大致看出正常情況下每五分鐘rank降低個數(shù)都不會超過200,因此,利用數(shù)據(jù)過濾功能,重新繪圖。效果如圖6。
代碼改動如下:

ofo_speed_rank = ofo_speed_rank[ofo_speed_rank['rank']<200]
ofo_speed_rank = ofo_speed_rank[ofo_speed_rank['rank']>0]
ofo_speed_rank['time'] = ofo_speed_rank.index
print(ofo_speed_rank)
plt.plot_date(ofo_speed_rank['time'],ofo_speed_rank['rank'])
plt.show()

從該散點圖中可以大致看出,點主要集中在40-100之間??梢蕴砑又本€更加直觀得觀察。如圖7所示。

plt.plot_date(ofo_speed_rank['time'],ofo_speed_rank['rank'])
x = pd.date_range(start='2019-3-22 09:00', periods=13, freq='H')
y1=[]
y2=[]
for i in range(13):
    y1.append(40)
    y2.append(100)
plt.plot(x,y1)
plt.plot(x,y2)
plt.show()
圖7

而且在40-100之間分布得相當均勻,并且從時間線上來觀察,也相當?shù)镁鶆颍梢酝茰yofo是通過機器來管控押金退款的,而不是人工管理。接下來求落在40-100之間的點的平均值即可。

ofo_speed_rank = ofo_speed_rank[ofo_speed_rank['rank']<100] 
ofo_speed_rank = ofo_speed_rank[ofo_speed_rank['rank']>40]
print(ofo_speed_rank.describe())
結果如下。
            rank
count  63.000000
mean   66.365079
std    14.520621
min    44.000000
25%    53.000000
50%    66.000000
75%    77.500000
max    99.000000

最大值99,最小值44,平均值66,標準差14.52。就以每五分鐘處理66個押金退款來說,每天工作十小時可處理7920個退款。像文中使用者一千五百萬的排名,需要等1894天,也就是大約五年的時間。
未來可期!

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容