2015-11-21 10 views
5

Scusate se questa è una domanda stupida, ma sono appena iniziato con python/numpy e non sono davvero sicuro dei modi più efficienti per fare le cose. Sto mettendo insieme un simulatore di N-body per alcuni studenti, ma per ora sto calcolando la forza tra le particelle facendo un loop sulle posizioni di quelle particelle che è prevedibilmente lente come la melassa. Fondamentalmente, dato un vettore x[i], desidero calcolare:eseguendo l'aggiunta esterna con numpy

n[i] = sum from j = 0 to n-1, j != i of (x[i]-x[j])^-2, 

utilizzando funzioni NumPy anziché loop. Se v'è un modo per eseguire esterno oltre/moltiplicazione:

m[i,j] = x[i]-x[j], 

m[i,j] = x[i]*x[j], 

ho potuto usarlo per fare il calcolo.

risposta

11

Tutte le funzioni universali che accettano due parametri di input hanno un attributo outer:

x = np.array([1, 2, 3]) 
np.subtract.outer(x, x) 

dà:

array([[ 0, -1, -2], 
     [ 1, 0, -1], 
     [ 2, 1, 0]]) 

e

np.multiply.outer(x, x) 

risultati in:

array([[1, 2, 3], 
     [2, 4, 6], 
     [3, 6, 9]]) 
+0

grazie per le informazioni! –

+1

Questa è una grande caratteristica! Per chi è interessato c'è ulteriore lettura sulla [documentazione ufunc] (https://docs.scipy.org/doc/numpy-1.13.0/reference/ufuncs.html#methods). – Annan

7

Molti operatori di base di NumPy come np.add, np.subtract, np.multiply ecc sono conosciuti come universal functions (ufuncs), e hanno (tra le altre cose) un metodo .outer:

import numpy as np 
a = np.arange(3) 
b = np.arange(5) 
c = np.add.outer(a, b) 
print(repr(c)) 
# array([[0, 1, 2, 3, 4], 
#  [1, 2, 3, 4, 5], 
#  [2, 3, 4, 5, 6]]) 

Un'altra tecnica molto potente per fare questo tipo di cosa è broadcasting:

print(repr(a[:, None] + b[None, :])) 
# array([[0, 1, 2, 3, 4], 
#  [1, 2, 3, 4, 5], 
#  [2, 3, 4, 5, 6]]) 

indicizzazione con None (o, in alternativa, con np.newaxis) inserisce un dimensione ew, quindi ha forma (3, 1) e b[None, :] ha forma (1, 5). La trasmissione "espande" il risultato lungo le dimensioni singleton, in modo che abbia la forma (3, 5).