Exemple: p>
Disons que la matrice A a rangée A0, A1, A2. Disons que le tableau B a des rangées B0, B1 P>
Les six combinaisons sont les suivantes: p>
A0-B0, A0-B1, A1-B0, A1-B1, A2-B0, A2-B1 P>
Dash représente la concaténation ( Comment faire cela rapidement pour arbitraire em> Nombre de tableaux (disons, a, b, c, ...)? p> Méthode rapide pour 2 tableaux: combinaison de toutes les lignes dans deux tableaux numpopy p> résultat du code pour la combinaison de 3 tableaux: P> np.hstack code>) p>
import numpy as np
def form_combinations(xs):
tot_size = np.sum([x.shape[1] for x in xs])
n_rows = [x.shape[0] for x in xs]
out = np.empty(n_rows + [tot_size])
n_cols = [x.shape[1] for x in xs]
cs = np.cumsum([0] + n_cols)
n = np.newaxis
out[:, :, :, cs[0]:cs[1]] = xs[0][:, n, n, :]
out[:, :, :, cs[1]:cs[2]] = xs[1][n, :, n, :]
out[:, :, :, cs[2]:cs[3]] = xs[2][n, n, :, :]
out = out.reshape(-1, tot_size)
return out
def main():
xs = [
np.arange(3)[np.newaxis, :],
np.arange(5, 20).reshape(3, 5),
np.arange(17, 38).reshape(3, 7)
]
print(xs)
out = form_combinations(xs)
print(out)
main()
3 Réponses :
Un moyen consiste à utiliser une compréhension de la liste où vous venez de boucler sur les trois tableaux d'annonce Utilisez htstack code> pour les empiler horizontalement.
%timeit np.array([np.hstack((i, j, k)) for i in a for j in b for k in c])
# 55.1 µs ± 2.61 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
Merci, mais avez besoin de le faire pour un nombre arbitraire de tableaux. iTertools.combination est la même que cette idée qui utilise des boucles de python lentes.
Pour le nombre arbitraire de tableaux, une approche progressive:
adapté de https://stackoverflow.com/a/49445693/7207392
>>> timeit(lambda: cartesian_product_pp([a,b,c]), number=1000)*1000 15.173833002336323 >>> timeit(lambda: combine([a,b,c]), number=1000)*1000 31.1394709860906 >>> timeit(lambda: np.array([np.hstack((i, j, k)) for i in a for j in b for k in c]), number=1000)*1000 51.15771805867553
Regardez iTertools.combinations (vous pouvez ensuite chaîner vos résultats en utilisant < Code> ithertools.chain.from_iterable code>)
Pourquoi ? C'est certes plus rapide que votre méthode de toute façon. Ou si vous voulez quelque chose de Scipy / Numpy: sciped.misc.comb
Si vous regardez le code donné dans le DOC, c'est (comme indiqué ci-dessus) un gros équivalent i> pour la compréhension. Le code réel derrière elle est bien optimisé.
Le code exemple ne fait même pas une liste (ou une compréhension de liste de n_row * n_row * n_row .. itérations). C'est une mission de tableau numpy. C Vitesse de boucle Python.
Ainsi, utilisez C, si vous vous plaignez de Python. Python n'est pas du tout sur la vitesse. Si vous voulez une vitesse, vous devez utiliser une meilleure langue pour cela.