J'essaie de parcourir l'espace des paramètres d'une fonction à 6 paramètres pour étudier son comportement numérique avant d'essayer de faire quelque chose de complexe avec, donc je recherche un moyen efficace de le faire.
Ma fonction prend des valeurs flottantes données un tableau numpy de 6 dim en entrée. Voici ce que j'ai essayé de faire au départ:
J'ai d'abord créé une fonction qui prend 2 tableaux et génère un tableau avec toutes les combinaisons de valeurs des deux tableaux
from numpy import *
def comb(a,b):
c = []
for i in a:
for j in b:
c.append(r_[i,j])
return c
Ensuite, reduce()
j'appliquais cela à m copies du même tableau:
def combs(a,m):
return reduce(comb,[a]*m)
Et puis j'évalue ma fonction comme ceci:
values = combs(np.arange(0,1,0.1),6)
for val in values:
print F(val)
Cela fonctionne mais c'est trop lent. Je sais que l'espace des paramètres est énorme, mais cela ne devrait pas être si lent. Je n'ai échantillonné que 10 6 (un million) points dans cet exemple et il a fallu plus de 15 secondes pour créer le tableau values
.
Connaissez-vous un moyen plus efficace de faire cela avec numpy?
Je peux modifier la façon dont la fonction F
prend ses arguments si c'est nécessaire.
la source
Réponses:
Dans la nouvelle version de
numpy
(> 1.8.x),numpy.meshgrid()
fournit une implémentation beaucoup plus rapide:la solution de @ pv
numpy.meshgrid()
utilisé pour être 2D seulement, maintenant il est capable de ND. Dans ce cas, 3D:Notez que l'ordre de la résultante finale est légèrement différent.
la source
np.stack(np.meshgrid([1, 2, 3], [4, 5], [6, 7]), -1).reshape(-1, 3)
donnera le bon ordreVoici une implémentation purement numpy. C'est environ 5 fois plus rapide que d'utiliser itertools.
la source
from sklearn.utils.extmath import cartesian
TypeError: slice indices must be integers or None or have an __index__ method
lancé parcartesian(arrays[1:], out=out[0:m,1:])
itertools.combinations est en général le moyen le plus rapide d'obtenir des combinaisons à partir d'un conteneur Python (si vous voulez en fait des combinaisons, c'est-à-dire des arrangements SANS répétitions et indépendants de l'ordre; ce n'est pas ce que votre code semble faire, mais je ne peux pas dire si c'est parce que votre code est bogué ou parce que vous utilisez la mauvaise terminologie).
Si vous voulez quelque chose de différent des combinaisons, peut-être que d'autres itérateurs dans itertools,
product
oupermutations
, pourraient mieux vous servir. Par exemple, il semble que votre code soit à peu près le même que:Tous ces itérateurs produisent des tuples, pas des listes ou des tableaux numpy, donc si votre F est pointilleux pour obtenir spécifiquement un tableau numpy, vous devrez accepter la surcharge supplémentaire de construction ou d'effacement et de re-remplissage d'un à chaque étape.
la source
Tu peux faire quelque chose comme ça
qui donne
la source
L'implémentation numpy suivante doit être d'env. 2x la vitesse de la réponse donnée:
la source
np.indices((n,...,n)).reshape(k,-1).T
fera l'affaire.Il semble que vous vouliez une grille pour évaluer votre fonction, auquel cas vous pouvez utiliser
numpy.ogrid
(open) ounumpy.mgrid
(étoffé):la source
vous pouvez utiliser
np.array(itertools.product(a, b))
la source
Voici encore une autre façon, en utilisant NumPy pur, sans récursion, sans compréhension de liste et sans boucles for explicites. C'est environ 20% plus lent que la réponse originale, et il est basé sur np.meshgrid.
Par exemple,
donne
la source
Pour une implémentation numérique pure du produit cartésien de tableaux 1D (ou de listes python plates), il suffit d'utiliser
meshgrid()
, de rouler les axes avectranspose()
et de remodeler à la sortie souhaitée:Notez que cela a la convention du dernier axe qui change le plus rapidement ("style C" ou "ligne-majeure").
Si vous voulez changer le premier axe le plus rapidement ("style FORTRAN" ou "colonne-majeur"), changez simplement le
order
paramètrereshape()
comme ceci:reshape((-1, N), order='F')
la source
Pandas
merge
propose une solution naïve et rapide au problème:la source