J'essaye d'utiliser numpy en Python pour résoudre mon projet.

J'ai un random binary array rndm = [1, 0, 1, 1] et un resource_arr = [[2, 3], 4, 2, [1, 2]]. Ce que j'essaie de faire, c'est de multiplier les éléments du tableau, puis d'obtenir leur somme. En tant que résultat attendu pour l'exemple ci-dessus, output = 5 0 2 3. J'ai du mal à résoudre ce problème à cause du nested array/list.

Jusqu'à présent, mon code ressemble à ceci:

   def fitness_score():

   output = numpy.add(rndm * resource_arr)
   return output


   fitness_score()

Je continue

ValueError: invalid number of arguments. 

Pour ce que je pense, c'est à cause de l'addition que j'essaie de faire. Toute aide serait appréciée. Je vous remercie!

1
Acee 1 juin 2020 à 14:07

3 réponses

Meilleure réponse

Je pense que la façon dont vous avez reconstruit resource_arr n'est pas un tableau numpy valide, car numpy traite les tableaux comme des matrices. Par conséquent, utiliser une liste python serait mieux:

def sum_nested(l):
    tmp = []

    for element in l:
        if isinstance(element, list):
            tmp.append(numpy.sum(element))
        else:
            tmp.append(element)

    return tmp

En utilisant cette fonction, nous vérifions pour chaque élément à l'intérieur de l s'il s'agit d'une liste. Si tel est le cas, nous additionnons les éléments de cette liste. Cependant, si l'élément rencontré n'est qu'un nombre, nous le laissons intact. Gardez à l'esprit que cela ne fonctionne que pour un seul niveau d'imbrication pour le moment.

Maintenant, si nous exécutons sum_nested([[2, 3], 4, 2, [1, 2]]), nous obtiendrons [5 4 2 3]. Il ne reste plus qu'à multiplier ce résultat par les éléments de rndm, ce qui peut être fait assez facilement en utilisant la fonction de multiplication de numpy:

def fitness_score(a, b):
    return numpy.multiply(a, sum_nested(b))
1
rjs44 1 juin 2020 à 12:11

Je n'ai pas beaucoup travaillé avec pandas/numpy donc je ne suis pas sûr que ce soit le moyen le plus efficace, mais cela fonctionne (au moins pour l'exemple que vous avez montré):

import numpy as np
rndm = [1, 0, 1, 1]
resource_arr = [[2, 3], 4, 2, [1, 2]]

multiplied_output = np.multiply(rndm, resource_arr)
print(multiplied_output)

output = []
for elem in multiplied_output:
  output.append(sum(elem)) if isinstance(elem, list) else output.append(elem)

final_output = np.array(output)
print(final_output)
0
Sowjanya R Bhat 1 juin 2020 à 11:23

Numpy est tout au sujet des tableaux non dentelés. Vous pouvez faire des choses avec des tableaux dentelés, mais le faire de manière efficace et élégante n'est pas anodin.

Presque toujours, essayer de trouver un moyen de mapper votre structure de données à une structure non imbriquée, par exemple, encoder les informations comme ci-dessous, sera plus flexible et plus performant.

resource_arr = (
    [0, 0, 1, 2, 3, 3]
    [2, 3, 4, 2, 1, 2]
)

Autrement dit, un entier indiquant la «ligne» à laquelle appartient chaque valeur, associé à un tableau de taille égale des valeurs elles-mêmes.

Cela peut `` sembler '' inutile quand on vient d'une façon de faire des tableaux de style C (omg plus de consommation de mémoire), mais rester à l'écart des structures de données imbriquées est presque certainement votre meilleur pari en termes de performances et de la quantité d'écosystème numpy / scipy qui sera réellement compatible avec votre représentation de données. S'il utilise vraiment plus de mémoire, c'est plutôt discutable; chaque nouvel objet python utilise une tonne d'octets, donc si vous n'avez que quelques éléments par imbrication, c'est aussi la solution la plus efficace en mémoire.

Dans ce cas, cela vous donnerait la solution efficace suivante à votre problème:

output = np.bincount(*resource_arr) * rndm
1
Eelco Hoogendoorn 1 juin 2020 à 12:06