我正在为工作创建推荐引擎,最终获得了8,000乘8,000个项目项目相似度矩阵。矩阵非常稀疏,所以我开始制作一个包含许多键的字典,其中每个键都指向一个列表,该列表是一个排序的产品推荐数组(以元组的形式)。我让这个工作,见下文。
In [191]: dictionary["15454-M6-ECU2="]
Out[191]:
[('15454-M-TSCE-K9=', 0.8),
('15454-M2-AC=', 0.52),
('15454-M6-DC-RF', 0.45),
('15454-M6-ECU2=', 0.63)]
但是,我现在在解释结果方面遇到了问题:
In [204]: sys.getsizeof(dictionary)
Out[204]: 786712
In [205]: sys.getsizeof(similarity_matrix)
Out[205]: 69168
即使我消除了大量的零(每个都用32或64位表示),为什么即使我们消除了矩阵中的稀疏性,对象大小也会增加?
答案 0 :(得分:1)
sys.getsizeof
只返回容器的大小,而不是容器加上里面项目的大小。无论所包含的值的大小如何,dict都返回相同的大小,并且每个键/值对仍然只有98个字节。它存储对密钥的引用和对值的引用以及散列/桶的其他开销。
>>> sys.getsizeof(dict((i,'a'*10000) for i in range(8000)))
786712
>>> sys.getsizeof(dict((i,'a'*1) for i in range(8000)))
786712
>>> 786712/8000
98
元组要小得多,只存储引用本身。
>>> sys.getsizeof(tuple((i,'a'*10000) for i in range(8000)))
64056
>>> sys.getsizeof(tuple((i,'a'*1) for i in range(8000)))
64056
>>> 64056/8000
8
答案 1 :(得分:0)
根据字典的大小,似乎每个可能的键都有一个键/值对(即使可能没有其他键与该键相似)。
我想你的代码看起来像这样:
# initialise sparse dict with one empty list of similar nodes for each node
sparse_dict = dict((key, []) for key in range(1000))
sparse_dict[0].append((2, 0.5)) # 0 is similar to 2 by 50%
def get_similarity(d, x, y):
for key, value in d[x]:
if key == y:
return value
return 0
assert get_similarity(sparse_dict, 0, 1) == 0
assert get_similarity(sparse_dict, 0, 2) == 0.5
但是,使用get
的{{1}}方法,您甚至可以实现更稀疏的词典
dict
每个字典的大小是:
# initialise empty mapping -- literally an empty dict
very_sparse_dict = {}
very_sparse_dict[0] = [(2, 0.5)] # 0 is similar to 2 by 50%
def get_similarity2(d, x, y):
for key, value in d.get(x, ()):
if key == y:
return value
return 0
# 0 not linked to 1, so 0% similarity
assert get_similarity2(very_sparse_dict, 0, 1) == 0
# 0 and 2 are similar
assert get_similarity2(very_sparse_dict, 0, 2) == 0.5
# 1 not similar to anything as it is not even present in the dict
assert get_similarity2(very_sparse_dict, 1, 2) == 0