背景:我正在努力加快k-means的执行时间。为此,我在k-means执行之前预先计算了平均值。这些装置存储在名为means_dict的字典中,该字典具有按升序排列的点ID序列作为关键字,然后通过下划线连接,并且作为值,这些点的平均值。 当我想在k-means执行期间访问dict_mean字典中设置的给定点的平均值时,我必须生成该点集的键,即按升序对id点进行排序并用下划线连接它们。 密钥生成指令需要很长时间,因为密钥可能包含数千个整数。
每个键都有一个由下划线分隔的整数序列" - "在字典中。我必须在通过下划线加入它们之前对整数序列进行排序,以使密钥唯一,我最终获得一个字符串键。问题是这个过程太长了。我想使用另一种类型的密钥,它允许避免对序列进行排序,并且密钥类型在访问,比较和搜索方面应该比字符串类型更快。
# means_dict is the dictionary containing as a key a string (sequence of
# integers joined by underscore "-", for example key="3-76-45-78-344")
# points is a dictionary containing for each value a list of integers
for k in keys:
# this joining instruction is so long
key = "_".join([ str(c) for c in sorted(points[k])])
if( key in means_dict ):
newmu.append( means_dict[key] )
答案 0 :(得分:1)
计算手段很便宜。
您是否对自己的计划进行了分析?他重新计算了多少时间?使用适当的numpy数组而不是python盒装数组,这应该非常便宜 - 绝对比构建任何这样的键便宜!
计算密钥的原因很简单:它意味着构建不同大小的对象。根据您的描述,似乎您将首先构建一个盒装整数列表,然后是一个盒子整数元组,然后将其序列化为一个字符串,然后再次复制该字符串以附加下划线。在计算实际平均值时,没有办法比简单 - 可矢量化聚合更快......
您甚至可以使用MacQueens方法来更新,而不是重新计算它们。但即便如此,也往往比重新计算它们慢。
如果你的方法最终比常规k-means慢10倍,我不会感到惊讶......并且可能比Hartigan和Wong的聪明的kmeans算法慢1000倍。