J'ai un tableau booléen ( bool_arr
) que je veux remplacer les nombres consécutifs non nuls le long des colonnes par leur nombre ( consécutif_count
) (qui est aussi le max / dernier numéro du groupe consécutif)
bool_arr = np.array([[1,1,1,1,0,1], [1,1,0,1,1,0], [1,1,1,1,1,1], [0,1,1,1,1,1], [1,1,1,1,1,0], [1,1,0,1,1,1]]) consecutive_cumsum = np.array([[1,1,1,1,0,1], [2,2,0,2,1,0], [3,3,1,3,2,1], [0,4,2,4,3,2], [1,5,3,5,4,0], [2,6,0,6,5,1]]) consecutive_count = consecutive_cumsum.copy() for x in range(consecutive_count.shape[1]): maximum = 0 for y in range(consecutive_count.shape[0]-1, -1, -1): if consecutive_cumsum[y,x] > 0: if consecutive_cumsum[y,x] < maximum: consecutive_count[y,x] = maximum else: maximum = consecutive_cumsum[y,x] else: maximum = 0 print(consecutive_count)
J'ai créé ma propre fonction qui obtient la somme cumulée d'éléments consécutifs non nuls le long des colonnes
consecutive_cumsum = [[1 1 1 1 0 1] [2 2 0 2 1 0] [3 3 1 3 2 1] [0 4 2 4 3 2] [1 5 3 5 4 0] [2 6 0 6 5 1]]
3 Réponses :
Utilisation de itertools.groupby
:
array([[3, 6, 1, 6, 0, 1], [3, 6, 0, 6, 5, 0], [3, 6, 3, 6, 5, 2], [0, 6, 3, 6, 5, 2], [2, 6, 3, 6, 5, 0], [2, 6, 0, 6, 5, 1]])
Output:
import itertools for i in range(b.shape[1]): counts = [] for k,v in itertools.groupby(b[:,i]): g = list(v) counts.extend([sum(g)] * len(g)) b[:,i] = counts
Les nouveaux mots clés (v1.15.0 je crois) append
et prepend
de np.diff
facilitent les choses:
def sum_stretches(a, axis=-1): a = a.swapaxes(-1, axis) dtype = np.result_type(a, 'i1') bnd = np.diff((a!=0).astype(dtype), axis=-1, prepend=0, append=0) *idx, last = np.where(bnd) A = np.concatenate([np.zeros((*a.shape[:-1], 1), a.dtype), a.cumsum(axis=-1)], -1)[(*idx, last)] bnd[(*idx, last)] *= (A[1::2]-A[::2]).repeat(2) return bnd[..., :-1].cumsum(axis=-1).swapaxes(-1, axis)
J'ai eu des problèmes de débordement avec la configuration de .astype (a.dtype)
pour bnd
et A
np.zeros (--- , a.dtype)
quand a.dtype = 'uint8' (opencv). Cela fonctionne si vous changez a.dtype
en 'int32'
@ Ta946 Mise à jour de la réponse. J'espère que cela résout le problème.
s'appuyant sur la réponse de paulpanzer pour les pauvres âmes (comme moi) qui n'ont pas numpy v1.15 +
def sum_stretches(a, axis=-1): a = a.swapaxes(-1, axis) padding = [[0,0].copy()]*a.ndim padding[-1] = [1,1] padded = np.pad((a!=0), padding, 'constant', constant_values=0).astype('int32') bnd = np.diff(padded, axis=-1) *idx, last = np.where(bnd) A = np.concatenate([np.zeros((*a.shape[:-1], 1), 'int32'), a.cumsum(axis=-1)], -1)[(*idx, last)] bnd[(*idx, last)] *= (A[1::2]-A[::2]).repeat(2) return bnd[..., :-1].cumsum(axis=-1).swapaxes(-1, axis)