Сохраняйте индекс того, сколько раз оператор if прошел внутри списка - PullRequest
1 голос
/ 28 марта 2020

Я хочу, чтобы вектор с единицами и нулями проверял, равен ли элемент в векторе 1. Если это единица, я хочу пометить этот элемент 2, а следующий равен 3 et c .. Это легко сделать за l oop.

x=np.array([1., 0., 0., 1., 0., 0., 1., 0., 1., 0.])

def label(vector):
U=np.copy(vector)
l=2
for i in range(len(U[:])):
    if occupied(U[i]):
        U[i]=l
        l+=1
return U

А затем

label(x)

возвращает массив

([2., 0., 0., 3., 0., 0., 4. , 0., 5., 0.])

Однако, поскольку эти массивы становятся больше и в конечном итоге становятся матрицами, я подумал, что было бы неплохо использовать списочные выражения.

def count_clusters(vector):
U=np.copy(vector)
label=2
U[:] = [label, label+=1 if el==1. else el for el in U[:]]
return U

Что должно выглядеть примерно так. Проблема состоит в том, чтобы сделать метку + = 1 одновременно в понимании списка, чтобы изменить значение элемента в массиве. И затем впоследствии используйте метку + 1 для следующей метки.

Так что мне было интересно, возможно ли это, или я должен просто придерживаться для l oop.

Ответы [ 2 ]

0 голосов
/ 28 марта 2020

Не оптимизировано для скорости, но смешно и без numpy.

def label(vector):
    return [sum(vector[:i+1]) * x for i, x in enumerate(vector)]

assert label([1, 0, 0, 1, 0, 1]) == [1, 0, 0, 2, 0, 3]

И то же самое с numpy.

import numpy as np

def label(vector):
    return np.cumsum(vector) * vector

assert (label([1, 0, 0, 1, 0, 1]) == np.array([1, 0, 0, 2, 0, 3])).all()
0 голосов
/ 28 марта 2020

Вы можете сделать то же самое с помощью итератора и использовать next():

import numpy as np

U = np.array([1., 0., 0., 1., 0., 0., 1., 0., 1., 0.])
c = iter(range(2, len(U)+2))

result = [float(next(c)) if x == 1 else x for x in U]
# [2.0, 0.0, 0.0, 3.0, 0.0, 0.0, 4.0, 0.0, 5.0, 0.0]

Также это другой способ использования itertools.count:

import numpy as np
from itertools import count

U = np.array([1., 0., 0., 1., 0., 0., 1., 0., 1., 0.])
c = count(2)

result = [float(next(c)) if x == 1 else x for x in U]
# [2.0, 0.0, 0.0, 3.0, 0.0, 0.0, 4.0, 0.0, 5.0, 0.0]
...