pandas之explode、resample

今天記一下處理數據中發現的pandas的好功能

1、explode ->拆分數據爲多行

我們遇到的車輛軌跡數據是這樣的,第一列是車輛的id,第二列是該車輛的軌跡信息,包括時間,經度,緯度

我們現在想做的是將最後一列按照第一列car_id拆分爲多行,即下圖所示 ,這樣才方便進行後續處理

最早我是拿循環加嵌套列表完成轉換的,後來發現pandas有explode這個函數,簡單來說,就是把datafrmae某一列中嵌套的列表拆分爲多行數據

import pandas as pd
data=pd.read_csv('tra_data.csv')
data['tra_info']=data['tra_info'].apply(eval)

導入數據並把軌跡列由字符串變爲列表類型

 

data=data.explode('tra_info')
可以看到執行explode後已經拆分爲了多行數據

data['time']=data.apply(lambda x :x.tra_info[0],axis=1)
data['lon']=data.apply(lambda x :x.tra_info[1],axis=1)
data['lat']=data.apply(lambda x :x.tra_info[2],axis=1)
data=data.drop(['tra_info'],axis=1)

把拆開的列表利用apply函數進一步分爲多列:

更多見官方文檔:

https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.explode.html

2、resample ->對時間序列重採樣

現在繼續利用上面處理過的的軌跡數據,按照5min統計車輛訂單時間分佈

這個時候就用到了resample

把日期列由字符串轉換爲時間類型:

resample_data=order_data.resample('5T',on='time').agg({"lon":'count'})

利用resample對時間序列數據重採樣(5T代表5min爲間隔):

季度是Q、月度是M、星期是W、N天是ND,時是H、分是T、秒是S

如5T代表5min,10S代表10秒,

https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.resample.html

可以看到第一列都變爲了以5min爲時間間隔的時刻


resample_data=resample_data.reset_index(drop=False)
#改變日期格式
resample_data['time_noday'] =resample_data['time'].apply(lambda x: x.strftime('%H:%M'))

新建一列只保存時間,去除日期,以便分組統計訂單:

 

result=resample_data.groupby(['time_noday'],as_index=False).agg({"lon":'mean'})

分組統計每個時刻的訂單量:

# 畫圖
times=result['time_noday'].tolist()
# 分時間區間,保證最後一位納入標籤
ticks=list(range(0,len(times),4))
if ticks[-1]!=len(times)-1:
    ticks.append(len(times)-1)
labels=[times[i] for i in ticks]
# bbox_props = dict(boxstyle="round", fc="w", ec="0.5", alpha=0)
mpl.rcParams['font.sans-serif'] = ['Times New Roman']
mpl.rcParams['font.sans-serif'] = [u'SimHei']
mpl.rcParams['axes.unicode_minus'] = False
fig= plt.figure(figsize=(8, 4),dpi=100)
ax1 = fig.add_subplot(111)
ax1.plot(result['lon'],'-',linewidth=1)
# ax1.legend(loc='best', frameon=False,fontsize = 10)
ax1.set_xlabel('Time',fontsize =10)
ax1.set_ylabel('Orders',fontsize =10)
ax1.set(xlim=[0,len(times)-1])
ax1.set_xticks(ticks)
ax1.set_xticklabels(labels, rotation=45, horizontalalignment='right')
ax1.tick_params(labelsize=6)
ax1.set_title('Time distribute',fontsize =8)
plt.savefig('time_distribute_5min.png',format='png', dpi=300)
plt.show()

畫出來軌跡訂單5min採樣的時間分佈 

改一下參數很容易得到

15min採樣的時間分佈

1h採樣的時間分佈

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