我正在使用熊貓來存儲,加載和操作財務數據。一個典型的數據文件是一個6000x4000 DataFrame(6000股票x 4000交易日期),如果說在給定的日期有一半的股票具有價值N/A,那麼它將以CSV格式大小爲200MB。我一直在使用具有16GB內存的工作站,該工作站已足以將此大小的整個CSV加載到內存中,執行各種計算,然後存儲結果。在典型的一天中,我最終在使用高峯時使用了大約10GB的RAM。我覺得我可以更有效地做事。我希望將該數字降低到2GB左右,這樣我就可以使用帶有4GB內存的普通筆記本電腦來運行我的幾款型號的每日更新。這是否合理?無論我的硬件如何,我是否會使用太多的內存?如何更好地管理我在熊貓中使用的記憶?
我明白上述的答案取決於我在做什麼的細節。這裏是我可能會遇到的函數類型的例子:
def momentum_strategy():
# prices.csv is a matrix containing stock prices for 6000 stocks
# and 4000 trading dates
prices = pd.read_csv("prices.csv")
# Daily stock returns
returns = prices/prices.shift(1) -1
# Annualized return volatility
volatility = pd.rolling_std(returns, 21, 21) * 252**0.5
# 6-month stock returns
trail6monthreturns = prices/prices.shift(21*6) - 1
# Rank of 6 month stock returns
retrank = trail6monthreturns.rank(axis=1, ascending=False)
# Portfolio of the top 100 stocks as measured by 6 month return
positions = retrank.apply(lambda x: np.where(x<= 100, 1, np.nan))
# Daily returns for top 100 stocks
uptrendreturns = positions * returns
# Daily return for 100 stock portfolio
portfolioreturns = uptrendreturns.mean(1)
return positions, portfolioreturns
我想過是使用HDF5存儲格式,而不是CSV的通過最近的測試中與大熊貓文件的審閱和stackoverlfow我看到在這種操作過程中,輸入/輸出速度更快,內存消耗更少。對此有何想法?例如,我將每日開盤價,最高價,最低價,收盤價,成交量,未平倉量,市盈率,盈利增長以及另外30種不同的度量值存儲在每個單獨的CSV中(如上例所示,通常6000個股票x 4000個交易日期)。如果推薦使用HDF5,應該將這些相同的DataFrame存儲在30個以上的獨立H5文件中?
在上面的函數中,如果我想要在函數完成後訪問一些中間結果,但不使用內存,那麼將結果存儲在包含HDF5文件?例如:
def momentum_strategy_hdf5():
# prices.csv is a matrix containing stock prices for 6000 stocks
# and 4000 trading dates
prices = pd.read_csv("prices.csv")
s = pd.HDFStore("temp.h5")
# Daily stock returns
s['returns'] = prices/prices.shift(1) -1
# Annualized return volatility
s['volatility'] = pd.rolling_std(s['returns'], 21, 21) * 252**0.5
# 6-month stock returns
s['trail6monthreturns'] = prices/prices.shift(21*6)
# Rank of 6 month stock returns
s['retrank'] = s['trail6monthreturns'].rank(axis=1, ascending=False)
# Portfolio of the top 100 stocks as measured by 6 month return
s['positions'] = s['retrank'].apply(lambda x: np.where(x<= 100, 1, np.nan))
# Daily returns for top 100 stocks
s['uptrendreturns'] = s['positions'] * s['returns']
# Daily return for 100 stock portfolio
s['portfolioreturns'] = s['uptrendreturns'].mean(1)
return s['positions'], s['portfolioreturns']
編輯:我剛剛測試了上面兩個函數,第一個花了15秒,第二個花了42秒。所以第二個寫得比較慢,但希望有更好的方法?
如果你的數據幀大多是空的,你看着使用[稀疏的結構(http://pandas.pydata.org/pandas-docs/stable/sparse.html)? – BrenBarn
謝謝,我只是做了一些測試。你確定to_sparse()對DataFrames產生內存差異嗎?我只是嘗試在Series和DataFrame上使用它。我可以在Series上使用to_sparse()而不是DataFrames來節省內存。雖然,當我用DataFrames的二進制文件寫入磁盤時,我確實看到了空間減少。 – bobo5645