a=[0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 -1, -1, -1, -1,-1, 0, 0, 0, 0, 0]
我希望能够获得重复点索引的中点,即
output_vector = [2, 8, 13, 19]
即output_vector [0]是第一个序列0, 0, 0, 0, 0
output_vector [1]是第二个重复序列1, 1, 1, 1, 1, 1, 1
output_vector [2]是第二个重复序列-1, -1, -1, -1,-1
答案 0 :(得分:2)
一种方法是使用itertools.groupby
查找组并计算其中点:
from itertools import groupby
a = [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1,-1, 0, 0, 0, 0, 0]
groups = [list(g) for _, g in groupby(a)]
output_vector = [sum(1 for x in groups[:i] for _ in x) + len(x) // 2 for i, x in enumerate(groups)]
# [2, 8, 14, 19]
答案 1 :(得分:2)
itertools
方法可能更好,更干净。尽管如此,这是一种使用math
和statistics
的方法,它要查找每组数字的起始索引和终止索引的中位数。
import math
import statistics as stat
a = [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0]
lastNum = None
startIdx = 0
midpts = []
for idx, x in enumerate(a):
if lastNum is not None and lastNum != x or idx == len(a) - 1:
midpts.append(math.floor(stat.median([startIdx, idx])))
startIdx = idx
lastNum = x
print(midpts)
# [2, 8, 14, 19]
答案 2 :(得分:2)
另一个基于itertools的解决方案,但效率更高。
from itertools import groupby
a = [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1,-1, 0, 0, 0, 0, 0]
output = []
psum = 0
for glen in (sum(1 for i in g) for k, g in groupby(a)):
output.append(psum + glen // 2)
psum += glen
print(output)
答案 3 :(得分:1)
基于C ++的@Matt M答案的实现
template<typename T>
std::vector<size_t> getPeaks(std::vector<T>& input_vector) {
std::vector<size_t> output;
T lastNum = 10000;
size_t startIdx = 0;
for (size_t i = 0; i < input_vector.size(); ++i) {
if ((lastNum != 10000 and lastNum != input_vector[i]) || (i == input_vector.size() - 1)) {
auto medianIdx = findMedian(startIdx, i);
output.emplace_back(medianIdx);
startIdx = i;
}
lastNum = input_vector[i];
}
return output;
}
size_t findMedian(size_t start, size_t end) {
return start + (end - start) / 2;
}