日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

数据挖掘:分享两个Pandas使用小陷阱

發布時間:2025/3/12 编程问答 17 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据挖掘:分享两个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就是我用來保存特征名字的列表,一開始的代碼長這樣:

def get_lag_feature(data, lag_length, lag_features, feature_cols=[]):qids = sorted(np.unique(data['QUEUE_ID']))data_out = pd.DataFrame()for qid in tqdm(qids):data_qid = data.loc[data['QUEUE_ID'] == qid].copy(deep=True)for i in range(lag_length):for col in lag_features:feature_col = '{}_lag{}'.format(col, i+1)data_qid[feature_col] = data_qid[col].shift(-i)feature_cols += [feature_col]data_qid.drop(columns=lag_features, inplace=True)data_qid = data_qid.iloc[:-10] # 去掉最后10條NAdata_out = data_out.append(data_qid)data_out = data_out.reset_index(drop=True)print(data_out.shape)return data_out

這一段生成的數據保存,竟然足足有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使用小陷阱的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。