我正在通过读取大数据集(约 250k 行)来构造一个大集合,为了提高效率,我决定使用集合理解来构造该集合,但我不断遇到内存错误,这是有道理的,因为我相信垃圾收集器在评估集合理解期间不起作用。实际源码如下:
def parsedData(filePath):
with open(filePath, 'rb') as rawData:
reader = csv.reader(rawData, delimiter=",")
allJobs = {Job(rawJob(row)) for row in reader}
return allJobs
有什么方法可以强制垃圾收集器在即将发生内存错误时进行清除吗?有没有更快的方法来做到这一点?使用 lambda 函数而不是集合理解会遇到同样的内存问题吗?
最佳答案
以下是可能发生这种情况的原因:
要创建一组唯一的自定义对象,您的对象至少必须实现 __eq__
和 __hash__
。
演示:
class Obj(object):
def __init__(self,val):
self.val=val
def __repr__(self):
return self.val
li=['i am uniq','i am uniq','i am uniq','not really','not really','not really']
print set(Obj(e) for e in li)
打印
set([i am uniq, i am uniq, not really, not really, i am uniq, not really])
现在添加所需的 __eq__
和 __hash__
方法:
class Obj(object):
def __init__(self,val):
self.val=val
self.hash=hash(val)
def __repr__(self):
return self.val
def __eq__(self,other):
return self.hash==other.hash
def __hash__(self):
return self.hash
li=['i am uniq','i am uniq','i am uniq','really','really','really']
print set(Obj(e) for e in li)
打印:
set([i am uniq, really])
如果没有适当的哈希和 eq,您会发现根本没有集合;您将获得一个基于 Jobs
obj id 的无序列表。换句话说,对于 Python 来说,即使您定义为“相同”的对象也会被视为不同的对象,因为每个对象都有不同的 obj id。这个“集合”实际上比等效列表要大一些。
除此之外 - 一种更有效的内存方法可能是使用 structured array在 numpy 中使用生成器逐行读取文件。
策略:
- 打开文件
- 确定文件的总行数——即文件中最坏情况的总记录
- 快退文件
- 读取第一条记录并根据行数据的记录(整数、 float 、字节等)确定 numpy 数组最有效的记录结构,这比 Python 对象中的等效记录结构要密集得多
- 快退文件
- 如果您希望使用哈希来统一数据,请将其添加到记录中
- 将 numpy 数组预分配为
行 X 记录
大小 - 创建一个生成器来逐行读取文件并将每条记录放入 numpy 数组中
- 不要添加重复记录(基于哈希)
- 调整 numpy 数组的大小以获取未添加的重复记录总数...
关于python - 使用集合理解避免内存错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15171717/