数据挖掘:分享两个Pandas使用小陷阱
原文首發:這里
?
這里主要分享數據分析過程中兩個很小的陷阱。
concat比較耗時
背景是有上萬個csv文件,想把他們整合到一個文件里,推薦整合后的格式保存為大數據里的.parquet,可以節省很多空間。
整合多文件時,不要著急用concat,而是先list到一起,最后統一concat。原因是concat的時候,需要考慮每個dataframe的index對齊,所以速度很慢。
我一開始的慢速寫法:
def concat_high_freq(base_dir, output_name='test_combined'):# 無法容忍的龜速!!!res = pd.DataFrame()for file in tqdm(os.listdir(base_dir)):if file.endswith('.csv'):file_data = pd.read_csv(os.path.join(base_dir, file))file_data['id'] = file.split('_')[-1].replace('.csv', "")#file_data['spcTime'] = file.split('_')[-2]res = pd.concat([res, file_data], axis=0)上萬個文件concat,一下午都沒跑完。主要就是因為每一次迭代都調用concat特別耗時。所以,盡量避免循環文件時每一步都concat,就快了幾百倍,改進后的寫法如下:
def concat_high_freq(base_dir, output_name='test_combined'):'''將高頻數據的多個文件合并到一起,綜合考慮到讀取速度與儲存大小,保存為parquet格式'''dfs = []for file in tqdm(os.listdir(base_dir)):if file.endswith('.csv'):file_data = pd.read_csv(os.path.join(base_dir, file))file_data['id'] = int(file.split('_')[-1].replace('.csv', ""))#file_data['spcTime'] = file.split('_')[-2]dfs.append(file_data)# res = pd.concat([res, file_data], axis=0)dfs.sort(key=lambda x: x.id[0])res = pd.concat(dfs)多循環注意別特征列重復
第二個的背景是生成特征時的小技巧。機器學習任務需要反復實驗,尤其是嘗試新特征時,因此每次靈活選擇特征是很重要的。我一般在特征開始時生成一個新list,然后每次嘗試新增一組特征時,都把新加的特征列名扔進這個深拷貝的list里。
不過,今天卻小翻車了一下,feature_cols就是我用來保存特征名字的列表,一開始的代碼長這樣:
這一段生成的數據保存,竟然足足有4G之多,內存直接爆炸后面都沒法跑了。然后,找到問題改進以后,就只有130M了,改進后就是下面這段代碼。
def get_lag_feature2(data, lag_length, lag_features, feature_cols=[]):temp = pd.DataFrame()qids = sorted(data['QUEUE_ID'].unique())for qid in tqdm(qids): # 按QUEUE_ID進行處理queue = data[data['QUEUE_ID'] == qid].copy(deep=True)# 生成時間窗數據for i in range(lag_length):for sf in lag_features:new_f = '%s_%d' % (sf, i + 1)queue[new_f] = queue[sf].shift(-i)# 刪除原來的列queue.drop(columns=lag_features, inplace=True)# 對于每個QUEUE_ID,丟棄最后10條有NAN值的數據queue = queue.head(queue.shape[0] - 10)temp = temp.append(queue)# 重設索引data = temp.reset_index(drop=True)return data主要問題出在哪里呢?就是最后返回的時候,我們可以輸出一下最后的維度
print(data_out[feature_cols].shape)為了找到問題,看一下之前保存的數據維度是(495024, 1052), 之后保存的數據的維度是(495024, 40)。 所以數據巨大的原因其實出在了feature_cols上。由于這里有三層循環,最外層的循環是針對每一個ID的,由于有幾百個ID,導致需要的列重復了幾百遍,占有的空間也就增大了幾百倍。想要解決這個問題,或者調整循環順序,或者把feature_cols換一種數據結構:集合set。
大概這就是copy-paste代碼,自己稍微一改就容易出錯的原因吧。
聯系方式
公眾號搜索:YueTan
總結
以上是生活随笔為你收集整理的数据挖掘:分享两个Pandas使用小陷阱的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Java用法】java 8两个List
- 下一篇: 数据竞赛:记录3天进入比赛Top3%的全