我已經使用Python和SciKitLearn堆棧創建了一個腳本來匹配巴西城市之間的氣候數據。目前,我正在使用帶有60M +條目的氣候集合的MongoDB,並且使用Pandas查詢並加入這些表格。如何使用Pandas和SciKitLearn Stack提高Python腳本的性能?
我用一個簡單的算法比較來自每個巴西城市的氣候數據,爲每個城市對生成一個最終得分。
問題是它需要很長時間(每對11秒)。這真的很慢,因爲我想獲得所有12M +可能組合的分數。我怎樣才能讓它更快?下面是相關代碼:
與MongoDB的(幾乎是瞬間)連接:
client = MongoClient('localhost', 27017)
db = client.agricredit_datafetcher_development
抓取氣候數據(快,但不是即時):從
base_weather_data = list(db.meteo_data_weather_data.find({'weather_station_id': ObjectId(base_weather_station['_id'])}))
target_weather_data = list(db.meteo_data_weather_data.find({'weather_station_id': ObjectId(target_weather_station['_id'])}))
return {'base_dataframe': pd.DataFrame(base_weather_data),
'target_dataframe': pd.DataFrame(target_weather_data)}
獲取數據內嵌(嵌套) Mongo收藏(緩慢):
base_dataframe = dataframes['base_dataframe'].set_index('analysis_date')['weather_forecast'].apply(pd.Series)
target_dataframe = dataframes['target_dataframe'].set_index('analysis_date')['weather_forecast'].apply(pd.Series)
查詢刪除空值並加入D ataFrames(快,但不是即時):
available_forecast_data = base_dataframe[base_dataframe['weather_forecast'] > 0][['weather_forecast']]
to_be_compared_data = target_dataframe[target_dataframe['weather_forecast'] > 0][['weather_forecast']]
join_dataframe = available_forecast_data.join(to_be_compared_data, how='inner', lsuffix='_base', rsuffix='_target')
然後我申請評分算法(這是相當快的,只是金額和平均),並然後將其插入我的蒙戈數據庫。
我該如何改進我的代碼?
這裏有幾點:
我敢肯定,如果我不使用創建一個新的數據框的
pd.Series
方法能夠處理嵌入MongoDB的數據(第三步)。我已經試過json.normalize
我的Mongo集合,然後將其轉換爲Dataframe,但速度很慢,而且當我這樣做時,一些數據會被搞亂。瓶頸在於描述的步驟。所有其他步驟(例如評分算法)都是即時的;
我依靠熊貓來做查詢,分組和創建數據框。這可以嗎?我很想嘗試Mongo Aggregation Framework,看看我是否有任何改進。這值得麼?
Hadoop/Spark是一種改進方法嗎?我很難理解他們在數據科學項目上的角色;
編輯:第三點解決!二手蒙戈聚集而不是應用pd.Series
方法對數據幀:
pipeline = [
{"$match" : {"weather_station_id": ObjectId(weather_station_id)}},
{"$project": {
'analysis_date': "$analysis_date",
'rainfall': "$rainfall.rainfall",
'agricultural_drought': "$rainfall.agricultural_drought",
'weather_forecast': "$weather_forecast.med_temp"
}
}
]
現在只需要〜1.2秒每對城市的。但我覺得我仍然可以改善這一點...現在瓶頸在weather_data
查詢。但是,它被索引,有什麼辦法可以讓它更快?
編輯2:並行化我的任務與JobLib
(https://pythonhosted.org/joblib/parallel.html)縮放我的腳本虛擬速度3-4倍:):
Parallel(n_jobs=4)(delayed(insert_or_read_scores_on_db)(city['name']) for city in cities)
還在尋找改進,雖然
順便說一下,'meteo_data_weather_data',這是60M +入口數據庫被'weather_station_id'編入索引,所以我認爲在第二步中沒有辦法提高性能。 –