我正在编写一个非常简单的脚本,它将计算文件中出现的次数。文件大小约为300Mb(1500万行),有3列。由于我逐行读取文件,因此我不希望python使用大量内存。最大值将略高于300Mb以存储计数字典。
但是,当我查看活动监视器时,内存使用量会超过1.5Gb。我究竟做错了什么 ?如果这是正常的,有人可以解释一下吗?感谢
import csv
def get_counts(filepath):
with open(filepath,'rb') as csvfile:
reader = csv.DictReader(csvfile, fieldnames=['col1','col2','col3'], delimiter=',')
counts = {}
for row in reader:
key1 = int(row['col1'])
key2 = int(row['col2'])
if (key1, key2) in counts:
counts[key1, key2] += 1
else:
counts[key1, key2] = 1
return counts
答案 0 :(得分:2)
我认为这很好,Python在你的情况下使用了这么多内存。这是我的机器上的测试:
Python 2.7.10 (default, Oct 23 2015, 19:19:21)
[GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.0.59.5)] on darwin
>>> file_size = 300000000
>>> column_count = 10
>>> average_string_size = 10
>>> row_count = file_size / (column_count * average_string_size)
>>> row_count
3000000
>>> import os, psutil, cPickle
>>> mem1 = psutil.Process(os.getpid()).memory_info().rss
>>> data = [{column_no: '*' * average_string_size for column_no in xrange(column_count)} for row_no in xrange(row_count)]
>>> mem2 = psutil.Process(os.getpid()).memory_info().rss
>>> mem2 - mem1
4604071936L
>>>
因此,包含10个长度为10的字符串的3000000 dict的完整列表正在使用更多4GB的RAM。
在您的情况下,我不认为csv数据占用RAM。这是你的counts
词典。
另一种解释是,从csv文件中逐个读取的dicts不会立即被垃圾收集(尽管我不确认)。
在任何情况下都使用专门的工具来查看占用内存的内容,例如https://pypi.python.org/pypi/memory_profiler
P.S。而不是做
if (key1, key2) in counts:
counts[key1, key2] += 1
else:
counts[key1, key2] = 1
待办事项
from collections import defaultdict
...
counts = defaultdict(int)
...
counts[(key1, key2)] += 1
答案 1 :(得分:0)
你可以尝试类似的东西:
import csv
def get_counts(filepath):
data = csv.reader(open(filepath), delimiter=',')
# Remove the first line if headers
fields = data.next()
counts = {}
[count[row[0], row[1]] = count.get((row[0], row[1]), 0) + 1 for row in data]
return counts
答案 2 :(得分:0)
试试这个
from collection import Counter
import csv
myreader = csv.reader( open(filename, 'r'))
Counter([each[:-1] for row in myreader] )
希望这有帮助。