1. 程式人生 > >python資料處理中的一些實際問題

python資料處理中的一些實際問題

前段時間參加阿里天池中的智慧交通預測挑戰賽,費了不少功夫初賽排名45進入了複賽,後續沒有時間繼續複賽了,但還是想總結一下,演算法就不詳述了,具體談談資料處理的一些問題與解決方案。適合想要學習的新手參考,歡迎大家提出意見

語言使用python+pycharm

資料與部分程式碼百度網盤地址:

http://pan.baidu.com/s/1jIGasnW

 1.      讀取資料

比賽中資料格式為txt,讀取方式有兩種,但為了方便進行後續的操作,採用python的庫pandas進行讀取,讀入後的格式為dataFrame,同時具有行列索引,如下:

data=pd.read_table('F:/tianchi/new_gy_contest_traveltime_training_data_second.txt'

,sep=';')

也可以用pd.read_csv,效果一樣

Sep用來說明txt的分隔符,需要觀察源資料,有的是or #or等等,需要靈活使用,不然讀出的資料是亂的

(1)有時候不想讀入全部資料,可以這麼辦

data=pd.read_table('F:/tianchi/new_gy_contest_traveltime_training_data_second.txt',sep=';',nrows=100)
這樣就只會讀取前100行
(2)表頭問題
如果你的資料有表頭,那麼讀入的時候會自動將表頭作為列名,如下:
如果沒有表頭,那麼問題來了,它會自動將第一行資料作為表頭,這不是我們想要的,那麼就要這樣:
A=pd.read_csv("mix_festival+weekend_result_0810.txt",sep='#',header=None)
那有的時候又需要使用自定義的表頭怎麼半呢,恩,手動新增
A.columns=['link_ID','date','time_interval','travel_time']

2.  合併不同資料

比賽中有三個資料表格,算是比較少的了,一般通過列名進行匹配合並

new_gy_contest_traveltime_training_data_second.txt

表頭為link_ID;date;time_interval;travel_time

gy_contest_link_info.txt

表頭為link_ID;length;width;link_class

gy_contest_link_top_update.txt

表頭為link_ID;in_links;out_links;

可以發現具有公共列名link_ID,這也是合併的基礎,合併方法如下:

data=pd.merge(資料1,資料2,on='link_ID')

3.列資料處理

(1)刪除列資料

data.drop('time_interval',axis=1)說明一下,改變列名即可刪除其他列,axis=1表示刪除方向為列,預設為行

(2)新增列資料

比如源資料有一列為time_interval,我要把它分為start_time和end_time兩列(這兒主要說明怎麼新增列,不是怎麼拆分)

可以這樣:

start_time=[]
for i in data['time_interval']:
    i=str(i)
    start_time.append(int(i.split(',')[0])) data['start_time']=start_time   #新增新的列start_time

要注意的是新增列的大小必須與原資料的大小相同,要不會發生意想不到的錯誤,可以試試

(3)排序

有時候你想排序,比如時間序列資料,怎麼辦,也簡單

按照一個的大小來排

data=data.sort_values('linkID')
同時按照兩個來排,注意先後順序
data=data.sort_values(['linkID','start_time'])

4.資料分組,批量讀入

(1)資料分組

比賽中一共有132條路的資料,想要檢視每一條路(link_ID)的資料怎麼辦,python幫你解決

for name,group in data.groupby('link_ID'):
group.to_csv('F:/tianchi/new_data/{}.txt'.format(name),index=False)
ps:namelink_ID分組後每條路的名字,group為相應的資料,之後將沒條路的資料存到本地txt檔案,名字為每條路的link_ID,index=False表示不會將行索引存下來,你也可以根據其他的來分組

(2)資料批量操作

剛才根據每條路的ID名分為了132個txt檔案,現在又想把它們合併為一個,也不難,只需要使用另外一個庫glob

filename=glob.glob(r'F:/tianchi/data/*.txt')
filenames = filename
with open('F:/tianchi/data.txt', 'w') as outfile:
    for fname in filenames:
        with open(fname) as infile:
            for line in infile:
                outfile.write(line)
這樣就會將資料儲存在outfile這個檔案裡面,但這樣做會有一個問題,如果132個檔案都有表頭,那麼會將表頭重複132次,這不是我們想要的,我們只需要一個表頭或者不要,這也是可以解決的:
filename=glob.glob(r'F:/tianchi/5-x/*.txt')
filenames = filename
with open('F:/tianchi/data-top-test.txt', 'w')as outfile:
    for fname in filenames:
        with open(fname) as infile:
            for line in islice(infile, 1, None):#讀取時跳過第一行
                outfile.write(line)
這樣就解決了,而且可以擴充套件

5.缺失資料處理

(1)檢視是否有缺失值並統計數量

sub_demo[['link_ID','date','time_interval','t']].shape
#輸出sub_demo上面相應列的大小
sub_demo[['link_ID','date','time_interval','t']].isnull().sum()

#輸出sub_demo上面相應列的缺失值的數目

(2)填充缺失值

一種方法是使用pandas的fillna方法,如下

data.fillna(value=1)
data.fillna(method='ffill',limit=2,axis=1)
引數說明,value表示用什麼填充,method表示填充方式,前向填充或者後向填充,即直接使用缺失值的前一個值或後一個值,limit表示可以連續填充的最大數量,axis表示填充的方向。

另一種方法是使用差值函式,如拉格朗日差值等

(3)時間缺失

比賽結果提交時需要自己構造132條路6月份8:00-9:00每隔兩分鐘的資料,那麼需要先生成相應的格式,如下:

程式碼30多行,比較簡單,放在網盤中了

6.將資料存為本地檔案

data.to_csv('F:/tianchi/result/result.txt',index=False,header=None,sep='#'#生成提交檔案
可以自己決定是否要索引,表頭,何種分隔符等

時間有限也就暫時說到這裡,還有缺失值匹配、時間格式等有機會再補充。