У меня есть отсортированный целочисленный массив, например, [0, 0, 1, 1, 1, 2, 4, 4]
, и я хотел бы определить, где начинаются целочисленные блоки и как долго они расположены.Размеры блоков невелики, но сам массив может быть очень большим, поэтому важна эффективность.Общее количество блоков также известно.
numpy.unique
делает трюк:
import numpy
a = numpy.array([0, 0, 1, 1, 1, 2, 4, 4])
num_blocks = 4
print(a)
_, idx_start, count = numpy.unique(a, return_index=True, return_counts=True)
print(idx_start)
print(count)
[0 0 1 1 1 2 4 4]
[0 2 5 6]
[2 3 1 2]
, но медленно.Я бы предположил, что, учитывая конкретную структуру входного массива, есть более эффективное решение.
Например, что-то такое простое, как
import numpy
a = numpy.array([0, 0, 1, 1, 1, 2, 3, 3])
num_blocks = 4
k = 0
z = a[k]
block_idx = 0
counts = numpy.empty(num_blocks, dtype=int)
count = 0
while k < len(a):
if z == a[k]:
count += 1
else:
z = a[k]
counts[block_idx] = count
count = 1
block_idx += 1
k += 1
counts[block_idx] = count
print(counts)
, дает размеры блока и простоеnumpy.cumsum
даст index_start
.Использование цикла Python, конечно, медленное.
Есть подсказки?