我想做一个列表中重复值之间所有间隔的直方图。我写了一些代码,但它使用了if语句的for循环。我经常发现,如果一个人能够使用巧妙的切片和/或预定义的python(numpy)方法来编写一个版本,那么就可以得到比使用for循环快得多的python代码,但是在这种情况下,我想不出任何方法来做到这一点。有人能提出一个更快或更具Python的方法吗?你知道吗
# make a 'histogram'/count of all the intervals between repeated values
def hist_intervals(a):
values = sorted(set(a)) # get list of which values are in a
# setup the dict to hold the histogram
hist, last_index = {}, {}
for i in values:
hist[i] = {}
last_index[i] = -1 # some default value
# now go through the array and find intervals
for i in range(len(a)):
val = a[i]
if last_index[val] != -1: # do nothing if it's the first time
interval = i - last_index[val]
if interval in hist[val]:
hist[val][interval] += 1
else:
hist[val][interval] = 1
last_index[val] = i
return hist
# example list/array
a = [1,2,3,1,5,3,2,4,2,1,5,3,3,4]
histdict = hist_intervals(a)
print("histdict = ",histdict)
# correct answer for this example
answer = { 1: {3:1, 6:1},
2: {2:1, 5:1},
3: {1:1, 3:1, 6:1},
4: {6:1},
5: {6:1}
}
print("answer = ",answer)
样本输出:
histdict = {1: {3: 1, 6: 1}, 2: {5: 1, 2: 1}, 3: {3: 1, 6: 1, 1: 1}, 4: {6: 1}, 5: {6: 1}}
answer = {1: {3: 1, 6: 1}, 2: {2: 1, 5: 1}, 3: {1: 1, 3: 1, 6: 1}, 4: {6: 1}, 5: {6: 1}}
^注意:我不关心dict中的顺序,因此此解决方案是可以接受的,但我希望能够在真正大型数组/列表上运行,我怀疑我当前的方法会很慢。你知道吗
在数据结构方面有一个明显的变化。与其使用
hist
的字典,不如使用defaultdict
的Counter
这让代码变得这会更快,因为
if
是用C写的,而且会更干净。你知道吗您可以通过仔细构造^{} 来消除设置循环。然后你只需要对输入列表进行一次扫描,就可以了。在这里,我将结果
defaultdict
改回常规的Dict[int, Dict[int, int]]
,但这只是为了让它打印得很好。你知道吗相关问题 更多 >
编程相关推荐