2017-09-17 3 views
1

On me donne un tableau de nombres 1D.Combinaison d'éléments de tableau d'une manière particulière et enregistrement

Je dois parcourir le tableau en ajoutant chaque élément consécutif pour former une somme. Une fois que cette somme atteint une certaine valeur, elle forme le premier élément d'un nouveau tableau. La somme est ensuite réinitialisée et le processus se répète, ce qui entraîne l'itération sur l'ensemble du tableau.

Par exemple si on leur donne: [1, 3, 4, 5, 2, 5, 3] et nécessitant la somme minimum pour être 5, la nouvelle matrice serait: [8, 5, 7]

Explicity: [1 + 3 + 4, 5, 2 + 5]

Je puis aussi besoin de garder une trace de la façon dont les éléments ont été combinés pour ce tableau particulier: je dois être à prendre tableau différent de la même longueur et combiner les éléments de la même manière que ci-dessus.

par exemple. donner la matrice [1, 2, 1, 1, 3, 2, 1] j'exige la sortie [4, 1, 5]

Explicity: [1 + 2 + 1, 1, 3 + 2 ]

J'ai accompli ceci avec des boucles d'i et des compteurs d'incrément, mais c'est très moche. Le tableau nommé « record » contient le nombre d'éléments anciens pour faire de chaque sommées élément du nouveau tableau à savoir [3, 1, 2]

import numpy as np 

def bin(array, min_sum): 

    num_points = len(array) 

    # Create empty output. 
    output = list() 
    record = list() 

    i = 0 

    while i < num_points: 

     sum = 0 
     j = 0 

     while sum < min_sum: 

      # Break out if it reaches end of data whilst in loop. 
      if i+j == num_points: 
       break 

      sum += array[i+j] 

      j += 1 

     output.append(sum) 
     record.append(j) 

     i += j 

    # The final data point does not reach the min sum. 
    del output[-1] 

    return output 

if __name__ == "__main__": 
    array = [1, 3, 4, 5, 2, 5, 3] 
    print bin(array, 5) 
+0

Quelle est votre question? Si vous avez accompli cela, il pourrait être intéressant de partager l'approche actuelle. –

+0

En fait, je n'ai pas compris votre question, pourquoi ne pas poster vos soi-disant codes moche, et je vais vous aider à le refactoriser et à le rendre plus pythonique? BTW, comment pourrions-nous obtenir [8, 5, 7] de [1, 3, 4, 5, 2, 5, 3] ?? –

+1

votre 2ème exigence n'est pas claire, comment ce '[1, 2, 1, 1, 3, 2, 1]' est transformé en '[4,1,5]' – RomanPerekhrest

Répondre

1

Je vous conseille de marcher simplement dans la liste. Ajoutez-le à un accumulateur comme the_sum (n'utilisez pas sum, puisqu'il s'agit d'un builtin), et dans le cas où the_sum atteint un nombre supérieur au min_sum, ajoutez-le et réinitialisez the_sum à zéro. Comme:

def bin(array, min_sum): 
    result = [] 
    the_sum = 0 
    for elem in array: 
     the_sum += elem 
     if the_sum >= min_sum: 
      result.append(the_sum) 
      the_sum = 0 
    return result

Les lignes où l'accumulateur est impliqué sont mises en gras.

Je laisse combiner l'autre tableau de la même manière comme un exercice, mais comme un indice: utiliser un accumulateur supplémentaire et zip à itérer sur les deux tableaux en même temps.

1

Voici une solution simple. which calcule une liste de valeurs booléennes où la valeur est vraie lorsque l'élément accumulé est égal ou supérieur à la valeur cible et calc calcule une accumulation en utilisant cette liste.

def which(l, s): 
    w, a = [], 0 
    for e in l: 
     a += e 
     c = (a >= s) 
     w.append(c) 
     if c: 
      a = 0 
    return w 

def calc(l, w): 
    a = 0 
    for (e, c) in zip(l, w): 
     a += e 
     if c: 
      yield a 
      a = 0 

est ici une démonstration interactive

>>> l1 = [1, 3, 4, 5, 2, 5, 3] 
>>> w = which(l1, 5) 
>>> w 
[False, False, True, True, False, True, False] 
>>> list(calc(l1, w)) 
[8, 5, 7] 
>>> l2 = [1, 2, 1, 1, 3, 2, 1] 
>>> list(calc(l2, w)) 
[4, 1, 5] 
0

Vous pouvez utiliser des solutions à court, j'ai découvert après une longue lutte avec les tableaux aplatissant.

Pour obtenir des sommes bornés utiliser:

f = lambda a,x,j,l: 0 if j>=l else [a[i] for i in range(j,l) if sum(a[j:i])<x] 

Ce sorties:

>>> f = lambda a,x,j,l: 0 if j>=l else [a[i] for i in range(j,l) if sum(a[j:i])< x] 
>>> a= [1, 3, 4, 5, 2, 5, 3] 
>>> f(a,5,0,7) 
[1, 3, 4] 
>>> sum(f(a,5,0,7)) 
8 
>>> sum(f(a,5,3,7)) 
5 
>>> sum(f(a,5,4,7)) 
7 
>>> 

Pour obtenir vos enregistrements utilisent la fonction:

>>> y = lambda a,x,f,j,l: [] if j>=l else list(np.append(j,np.array(y(a,x,f,j+len(f(a,x,j,l)),l)))) 

De là, vous pouvez obtenir à la fois tableau d'enregistrements et de sommes:

>>> listt=y(a,5,f,0,len(a)) 
>>> listt 
[0.0, 3.0, 4.0, 6.0] 
>>> [sum(f(a,5,int(listt[u]),len(a))) for u in range(0,len(listt)-1)] 
[8, 5, 7] 
>>> 

Maintenant, le peu de magie vous pouvez même l'utiliser comme une limite conditionnelle indice pour le second vecteur:

>>> b=[1, 2, 1, 1, 3, 2, 1] 
>>> [sum(f(b,5,int(listt[u]),int(listt[u+1]))) for u in range(0,len(listt)-1)] 
[4, 1, 5] 
>>>