J'ai une liste python de longueur variable remplie de 0s
et 1s
.
Je veux créer une nouvelle liste où tous les 1s code > sont étendus par un certain
offset
.
Exemples:
offset = 1 l_old = [0,0,1,0] l_new = [] for i,l in enumerate(l_old): hit = False for o in range(offset+1)[1:]: if (i+o<len(l_old) and l_old[i+o]) or (i>0 and l_old[i-o]): hit = True break if hit or l_old[i]: l_new.append(1) else: l_new.append(0)
Mon code de solution n'est pas très rapide et non utilisez toutes les opérations numpy / vectorisation / bitwise. Mais je suppose que certaines de ces méthodes devraient être applicables ici.
offset = 1 l1 = [0,0,1,0] l1_new = l[0,1,1,1] l2 = [1,0,0,0,1,0,1,0,0] l2_new = [1,1,0,1,1,1,1,1,0]
Astuce: La solution doit être rapide et générique pour toute liste de
0
et1
et pour toutoffset
3 Réponses :
Vous pouvez convolver avec un tableau de ceux, et clip
le résultat:
from skimage.morphology import binary_dilation a = np.array(l2) w = offset*2 +1 binary_dilation(a, np.ones(w)).view('i1') # array([1, 1, 0, 1, 1, 1, 1, 1, 0], dtype=int8)
Ou nous avons également skimage.morphology.binary_dilation
:
def expand1s(a, offset): w = offset*2 +1 return np.convolve(a, np.ones(w), mode='same').clip(0,1) expand1s(l1, 1) # array([0., 1., 1., 1.]) expand1s(l2, 1) # array([1., 1., 0., 1., 1., 1., 1., 1., 0.])
J'aime celui-ci, mais la liste retournée doit contenir des entiers, donc appeler list (map (int, expand1s (a, offset)))
est nécessaire
Juste .astype (int)
, puisque nous utilisons numpy @gustavz
Voici une solution qui utilise une compréhension simple avec une tranche basée sur offset
:
>>> def expand_ones(old: list, offset: int) -> list: ... return [1 if any( ... old[max(0, i-offset):min(len(old), i+offset+1)] ... ) else 0 for i in range(len(old))] ... >>> expand_ones([1, 0, 0, 0, 1, 0, 1, 0, 0], 1) [1, 1, 0, 1, 1, 1, 1, 1, 0] >>> expand_ones([1, 0, 0, 0, 1, 0, 1, 0, 0], 2) [1, 1, 1, 1, 1, 1, 1, 1, 1]
Voici une solution temporelle linéaire (O (n + offset)):
[0 0 0 1 0 0 0 0 0 1] [0 1 1 1 1 1 0 1 1 1]
Exemple de sortie:
import numpy as np def symm_dil(a,hw): aux = np.zeros(a.size+2*hw+1,a.dtype) aux[:a.size] = a aux[2*hw+1:] -= a return np.minimum(aux.cumsum(),1)[hw:-hw-1] #example rng = np.random.default_rng() a = rng.integers(0,2,10) print(a) print(symm_dil(a,2))
Je viens de jeter un coup d'œil à ce que cela fait réellement. Très belle utilisation de sperme et efficace