地鐵大數據挖掘之數據預處理——從原始一卡通數據提取城市地鐵客流(一)

    這是很久以前寫的一段代碼,很簡單很基礎。最近突然用到,這裏把它分享出來,希望可以爲有需要的朋友提供幫助。

   以及歡迎閱讀這一系列第二篇:地鐵大數據挖掘之客流數據預處理——從原始一卡通數據提取城市地鐵客流(二)


1 解壓文件

    這裏以上海城市開放大賽提供的數據爲樣例(提取碼zlsy),需要的朋友可以進行下載。把數據進行解壓後,看到是一個個壓縮文件:

    接下來,可以用下面這段代碼對這些數據進行解壓:

import gzip  
import os  
from datetime import datetime 
import shutil

#解壓文件
def un_gz(file_name):  
    """ungz zip file"""  
    f_name = file_name.replace(".gz", "")  
    #獲取文件的名稱,去掉  
    g_file = gzip.GzipFile(file_name)  
    #創建gzip對象  
    open(f_name, "wb+").write(g_file.read())  
    #gzip對象用read()打開後,寫入open()建立的文件中。  
    g_file.close()  
    #關閉gzip對象 

date_l=[datetime.strftime(x,'%Y%m%d') for x in list(pd.date_range('20150401','20150430'))]
file_name=[]
for x in date_l:
    filename="SPTCC-"+x+'.csv.gz'
    file_name.append(filename)
for each in file_name:
    un_gz(each)

#創建文件夾
os.mkdir('railway_data')

#將解壓後的文件移至新文件夾
file_name2=[]
for x in date_l:
    filename="SPTCC-"+x+'.csv'
    file_name2.append(filename)
for each in file_name2:
    shutil.move(each,"railway_data")

2 提取客流    

    進去新創建的文件夾,可以先看一下數據的樣子:

import pandas as pd

f=open("SPTCC-20150401.csv")
data=pd.read_csv(f,header=0,names=["cardnum","date","time","linename","business","figure","attribute"])
data.head()

    這一步我們想得到的結果是某個站點每十分鐘的客流。從“business”字段可以看出,這裏的數據不僅有地鐵的,還有公交等其他數據。而且根據常識,地鐵客流是分進站和出戰的。因此,我們也想分別得到某一時間片內某站的地鐵進站和出站客流。

 2.1 提取地鐵數據

    剛剛講到,可以通過“business”這一字段判斷是否爲地鐵數據,因此代碼如下:

def railway_data(data):
    RailWay=data[data["business"]=="地鐵"]
    return RailWay

2.2 劃分相應時間片

    這裏用到的字段是“time”。可能會有很方便的做法,如果有更好的方便也歡迎朋友們批評指正。我這裏用到的是一種十分笨的辦法,我把時間看作“六十進制”的數字,對時、分和秒分別乘以3600、60和1,最後獲得一個類似於“時間戳”一樣的數字,再對時間片進行劃分。

#計算“時間戳”
def timespan(data):
    data["timespan"]=data["time"].apply(lambda x:x[:2]).astype(int)*3600+data["time"].apply(lambda x:x[3:5]).astype(int)*60+data["time"].apply(lambda x:x[6:]).astype(int)
    return data

#劃分時間片
def timebins(data):
    #計算每個時間片的秒數間隔
    seconds=[600*x for x in range(0,145)]
    #給時間片做標籤
    label=[x for x in range(1,145)]
    #這裏利用的是pandas的分箱操作
    _10min=pd.cut(data["timespan"],bins=seconds,labels=label)
    _10mins=_10min.get_values()
    data['_10mins']=_10mins
    return data

2.3 提取進出站客流

    這裏利用的是字段“figure"。很明顯,根據日常生活經驗,進站時打卡是不花錢的,出站時根據里程數計費。所以,這裏根據“figure"值是否爲0判斷進出站。

def input_data(data):
    inputdata=data[data["figure"]==0]
    return inputdata

def output_data(data):
    output=data[data["figure"]>0]
    return output

2.4 對客流進行統計

    之後,對每一個站點的不同時間片客流進行統計:

def groupby_data(data):
    grouped_data=data.groupby(["linename","_10mins"]).count()
    manageG=grouped_data.reset_index(drop=False)
    del grouped_data
    gc.collect()
    manageG.drop(["cardnum","date","time","business","figure","attribute"],axis=1,inplace=True)
    manageG.rename(columns={"timespan":"passengernums"},inplace=True)
    return manageG

2.5 融合進出站客流

#mi是進站數據,mo是出站數據
def merge_data(mi,mo):
    final_data=pd.merge(mi,mo,how="outer",on=["linename","_10mins"])
    final_data.rename(columns={"passengernums_x":"inputnums","passengernums_y":"outputnums"},inplace=True)
    FinalData=final_data.fillna(0)
    del final_data
    gc.collect()
    return FinalData

3 整合代碼

    最後,把所有的代碼整合在一起,並對一個月30天數據進行處理:

import pandas as pd
from datetime import datetime
import os
#clear memory
import gc 

os.mkdir("_10mins")

def open_data(i):
    f=open(i)
    data=pd.read_csv(f,header=0,names=["cardnum","date","time","linename","business","figure","attribute"])
    return data

def railway_data(data):
    RailWay=data[data["business"]=="地鐵"]
    return RailWay

​
#計算“時間戳”
def timespan(data):
    data["timespan"]=data["time"].apply(lambda x:x[:2]).astype(int)*3600+data["time"].apply(lambda x:x[3:5]).astype(int)*60+data["time"].apply(lambda x:x[6:]).astype(int)
    return data

#劃分時間片
def timebins(data):
    #計算每個時間片的秒數間隔
    seconds=[600*x for x in range(0,145)]
    #給時間片做標籤
    label=[x for x in range(1,145)]
    #這裏利用的是pandas的分箱操作
    _10min=pd.cut(data["timespan"],bins=seconds,labels=label)
    _10mins=_10min.get_values()
    data['_10mins']=_10mins
    return data

​​
def input_data(data):
    inputdata=data[data["figure"]==0]
    return inputdata

def output_data(data):
    output=data[data["figure"]>0]
    return output

​​
def groupby_data(data):
    grouped_data=data.groupby(["linename","_10mins"]).count()
    manageG=grouped_data.reset_index(drop=False)
    del grouped_data
    gc.collect()
    manageG.drop(["cardnum","date","time","business","figure","attribute"],axis=1,inplace=True)
    manageG.rename(columns={"timespan":"passengernums"},inplace=True)
    return manageG

​​
#mi是進站數據,mo是出站數據
def merge_data(mi,mo):
    final_data=pd.merge(mi,mo,how="outer",on=["linename","_10mins"])
    final_data.rename(columns={"passengernums_x":"inputnums","passengernums_y":"outputnums"},inplace=True)
    FinalData=final_data.fillna(0)
    del final_data
    gc.collect()
    return FinalData

​
date=[datetime.strftime(x,'%Y%m%d') for x in list(pd.date_range('20150401','20150430'))]
for i in date:
    filename="SPTCC-"+i+".csv"
    SHData=open_data(filename)
    
    RailWay=railway_data(SHData)
    del SHData
    gc.collect()
    
    TimeSpan_data=timespan(RailWay)
    del RailWay
    gc.collect()
    
    timebins_data=timebins(TimeSpan_data)
    del TimeSpan_data
    gc.collect()
    
    inputdata=input_data(timebins_data)
    output=output_data(timebins_data)
    del timebins_data
    gc.collect()
    
    manageinput=groupby_data(inputdata)
    manageoutput=groupby_data(output)
    del inputdata
    gc.collect()
    del output
    gc.collect()
    
    savedata=merge_data(manageinput,manageoutput)
    del manageinput
    gc.collect()
    del manageoutput
    gc.collect()
    
    fn=str(i)+".csv"
    path=os.path.join("_10mins",fn)
    savedata.to_csv(path)

    最後看一下得到的結果:

    ”_10min“字段代表所處的時間片(比如1代表0:00-0:10),inputnums代表進站客流,outputnums代表出站客流。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章