我遇到一个问题,我必须在循环中生成大型DataFrames(每次两次2000 x 800 pandas DataFrames时计算50次迭代)。我想将结果保存在更大的DataFrame或类似字典的结构中。 使用pandas.concat时,我在循环中的某个时刻出现内存错误。使用numpy.append将结果存储在numpy数组的字典中而不是DataFrame中时,会发生同样的情况。在这两种情况下,我仍然有很多可用内存(几GB)。对于大熊猫或numpy来说,这是否有太多数据需要处理?有没有更节省内存的方法来存储我的数据而不将其保存在磁盘上?
例如,nbIds
大于376时,以下脚本失败:
import pandas as pd
import numpy as np
nbIds = 376
dataids = range(nbIds)
dataCollection1 = []
dataCollection2 = []
for bs in range(50):
newData1 = pd.DataFrame( np.reshape(np.random.uniform(size =
2000 * len(dataids)),
(2000,len(dataids ))))
dataCollection1.append( newData1 )
newData2 = pd.DataFrame( np.reshape(np.random.uniform(size =
2000 * len(dataids)),
(2000,len(dataids ))))
dataCollection2.append( newData2 )
dataCollection1 = pd.concat(dataCollection1).reset_index(drop = True)
dataCollection2 = pd.concat(dataCollection2).reset_index(drop = True)
nbIds
为665或更高时,以下代码失败
import pandas as pd
import numpy as np
nbIds = 665
dataids = range(nbIds)
dataCollection1 = dict( (i , np.array([])) for i in dataids )
dataCollection2 = dict( (i , np.array([])) for i in dataids )
for bs in range(50):
newData1 = np.reshape(np.random.uniform(size = 2000 * len(dataids)),
(2000,len(dataids )))
newData1 = pd.DataFrame(newData1)
newData2 = np.reshape(np.random.uniform(size = 2000 * len(dataids)),
(2000,len(dataids)))
newData2 = pd.DataFrame(newData2)
for i in dataids :
dataCollection1[i] = np.append(dataCollection1[i] ,
np.array(newData1[i]))
dataCollection2[i] = np.append(dataCollection2[i] ,
np.array(newData2[i]))
我确实需要每次都计算两个DataFrame,对于i
的每个元素dataids
,我需要获得一个pandas Series或一个包含为{{1}生成的50 * 2000个数字的numpy数组}。理想情况下,我需要能够在i
等于800或更多的情况下运行它。
有这么简单的方法吗?
我使用的是32位Python和Python 2.7.5,pandas 0.12.0和numpy 1.7.1。
非常感谢你的帮助!
答案 0 :(得分:6)
这基本上就是你在做的事情。请注意,如果您在之前或之后进行与DataFrame的对话,则从内存角度来看,它没有太大区别。
但你可以指定dtype ='float32'来有效地减少你的记忆。
In [45]: np.concatenate([ np.random.uniform(size=2000 * 1000).astype('float32').reshape(2000,1000) for i in xrange(50) ]).nbytes
Out[45]: 400000000
In [46]: np.concatenate([ np.random.uniform(size=2000 * 1000).reshape(2000,1000) for i in xrange(50) ]).nbytes
Out[46]: 800000000
In [47]: DataFrame(np.concatenate([ np.random.uniform(size=2000 * 1000).reshape(2000,1000) for i in xrange(50) ]))
Out[47]:
<class 'pandas.core.frame.DataFrame'>
Int64Index: 100000 entries, 0 to 99999
Columns: 1000 entries, 0 to 999
dtypes: float64(1000)
答案 1 :(得分:2)
直接(但使用硬盘驱动器)的方式是简单地使用搁置(硬盘驱动器字典):http://docs.python.org/2/library/shelve.html
答案 2 :(得分:2)
正如使用thetheathstar,Boud和Jeff在评论中所建议的,切换到64位python可以解决这个问题。
如果丢失精度不是问题,那么使用Jeff建议的float32数据类型也会增加可以在32位环境中处理的数据量。