不幸的是,我沒有一個numpy的/矢量解決一般問題。
這裏是一個通用解決方案,它適用於任何深度。您的問題的第一部分對應於深度= 1,第二至深度= 2。該解決方案也適用於更高的深度。很明顯,如果你只想解決depth = 1的情況,可以想出一個更簡單的解決方案。但是,對於這個問題,普遍性增加了複雜性。
from itertools import groupby, chain, izip
ilen = lambda it: sum(1 for dummy in it)
def get_squeezed_counts(a):
"""
squeeze a sequence to a sequnce of value/count.
E.g. ['a', 'a', 'a', 'b'] --> [['a',3], ['b',1]]
"""
return [ [ v, ilen(it) ] for v, it in groupby(a) ]
def get_element_dist(counts, index, depth):
"""
For a given index in a "squeezed" list, return the distance (in the
original-array) with a given depth, or None.
E.g.
get_element_dist([['a',1],['b',2],['c',1]], 0, depth=1) --> 1 # from a to first b
get_element_dist([['a',1],['b',2],['c',1]], 1, depth=1) --> 2 # from first b to c
get_element_dist([['a',1],['b',2],['c',1]], 0, depth=2) --> 3 # from a to c
get_element_dist([['a',1],['b',2],['c',1]], 1, depth=2) --> None # from first b to end of sequence
"""
seen = set()
sum_counts = 0
for i in xrange(index, len(counts)):
v, count = counts[i]
seen.add(v)
if len(seen) > depth:
return sum_counts
sum_counts += count
# reached end of sequence before finding the next value
return None
def get_squeezed_dists(counts, depth):
"""
Construct a per-squeezed-element distance list, by calling get_element_dist()
for each element in counts.
E.g.
get_squeezed_dists([['a',1],['b',2],['c',1]], depth=1) --> [1,2,None]
"""
return [ get_element_dist(counts, i, depth=depth) for i in xrange(len(counts)) ]
def get_dists(a, depth):
counts = get_squeezed_counts(a)
squeezed_dists = get_squeezed_dists(counts, depth=depth)
# "Unpack" squeezed dists:
return list(chain.from_iterable(
xrange(dist, dist-count, -1)
for (v, count), dist in izip(counts, squeezed_dists)
if dist is not None
))
print get_dists(['a','b','b','c','d','a','b','b','c','c','c','d'], depth = 1)
# => [1, 2, 1, 1, 1, 1, 2, 1, 3, 2, 1]
print get_dists(['a','a','a'], depth = 1)
# => []
print get_dists(['a','b','b','c','d','a','b','b','c','c','c','d'], depth = 2)
# => [3, 3, 2, 2, 2, 3, 5, 4]
print get_dists(['a','b','a', 'b'], depth = 2)
# => []
對於python3,更換xrange->range
和izip->zip
。
以下數組'np.array(['a','a','a'])'的預期輸出是什麼? – CoryKramer
一個空數組[]。 – imsc
對於「兩個新元素」距離,「['a','b','a','b']'的輸出應該是什麼? – shx2