gpt4 book ai didi

python - 到 numpy 数组中非连续元素的距离

转载 作者:行者123 更新时间:2023-11-28 18:43:39 25 4
gpt4 key购买 nike

使用 numpyitertools 是确定到下一个非连续元素的距离的有效方法。

> import numpy as np 
> a=np.array(['a','b','b','c','d','a','b','b','c','c','c','d'])

我希望输出是。

[1, 2, 1, 1, 1, 1, 2, 1, 3, 2, 1]

扩展这个,我想要到两个新元素的距离。预期的输出应该是

[3, 3, 2, 2, 2, 3, 5, 4]

a后的两个新元素是b(二)和c,依此类推。

编辑 1我有两个版本用于查找下一个新元素:

import numpy as np                                                           
a = np.array(['a', 'b', 'b', 'c', 'd', 'a', 'b', 'b', 'c', 'c', 'c', 'd'])

# Using numpy
u, idx = np.unique(a, return_inverse=True)
idx = np.diff(idx)
idx[idx < 0] = 1
idx[idx > 1] = 1
count = 1
while 0 in idx:
idx[np.diff(idx) == count] = count+1
count += 1 │
print idx

# Using loop
oldElement = a[0]
dist = []
count = 1
for elm in a[1:]:
if elm == oldElement:
count += 1
else:
dist.extend(range(count, 0, -1))
count = 1
oldElement = elm
print dist

但是这种方法不能简单地扩展到找到 2 个新元素。

最佳答案

不幸的是,我没有针对一般问题的 numpy/向量化解决方案。

这是一个通用解决方案,适用于任何深度。您问题的第一部分对应于depth=1,第二部分对应于depth=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->rangeizip->zip

关于python - 到 numpy 数组中非连续元素的距离,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23068872/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com