gpt4 book ai didi

python - 如何更好地管理我在 Pandas 中的内存使用?

转载 作者:太空宇宙 更新时间:2023-11-03 14:24:12 25 4
gpt4 key购买 nike

我正在使用 Pandas 来存储、加载和操作财务数据。一个典型的数据文件是一个 6000x4000 的 DataFrame(6000 只股票 x 4000 个交易日期),如果说一半的股票在给定日期具有 N/A 值(value),则 CSV 格式的大小为 200MB。我一直在使用一个有16GB内存的工作站,这足以将这个大小的整个CSV加载到内存中,进行各种计算,然后存储结果。在典型的一天中,我最终会在高峰使用期间使用大约 10GB 的 RAM。我觉得我可以更有效地做事。我想将这个数字降低到 2GB 左右,这样我就可以使用配备 4GB RAM 的普通笔记本电脑运行我的多个型号的每日更新。这合理吗?无论我的硬件如何,我是否使用了过多的内存?

我理解上述问题的答案取决于我正在做的事情的细节。这是我可能运行的函数类型的示例:

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,因为通过最近的测试和对 pandas 文档和 stackoverlfow 的细读,我发现它的输入/输出速度要快得多,并且在此类操作期间占用的内存更少。对此有什么想法吗?例如,我将每日开盘价、最高价、最低价、收盘价、交易量、已发行股票、市盈率、 yield 增长以及另外 30 种不同的衡量指标存储在单独的 CSV 中,每个指标(如上例所示,通常为 6000 只股票 x每个 4000 个交易日期)。如果建议切换到 HDF5,我是否应该将这些相同的数据帧存储在 30 多个单独的 H5 文件中?

在上面的函数中,如果我想在函数完成后访问一些中间结果,但又不想用完内存,那么将结果存储在包含 HDF5 的“temp”文件夹中是否有意义文件?例如:

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秒。所以写的第二个要慢得多,但希望有更好的方法吗?

最佳答案

这是此类数据的典型工作流程:

  • 1) 读入 csv 数据,转换为 DataFrame,强制数据类型,使用 HDFStore 写出(根据您的需要可以是“固定”或“表格”格式)。这是一个单独的过程,然后退出该过程。当数据集很大时,我会以逻辑格式(例如日期范围)读取它,然后输出一个“表格”格式的 HDF5 文件。然后可以追加到这个。

  • 2) 查询(同样可以基于日期或其他一些条件)。执行计算,然后写出 NEW HDF5 文件。这可以并行完成(多个进程)。确保您在每个进程中编写单独的文件。

  • 3) 将先前的数据文件组合成单个 HDF5 文件。这是一个单一的过程事件。

  • 4) 根据需要重复 2 和 3。

关键是执行离散的步骤,在中间写出中间数据,并在中间退出进程。这保持了可管理的内存数据大小,并使内存计算速度更快。此外,这允许对只读 HDF5 文件进行 CPU 密集型操作的多次处理。

重要的是在单独的系统进程中执行此操作以允许系统回收内存。

HTH

关于python - 如何更好地管理我在 Pandas 中的内存使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23075020/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com