2016-04-28 5 views
0

Ich habe zwei Arrays gleicher Größe und möchte eine Funktion (hier binom_test) auf jedes Paar Elemente anwenden, die sich an der gleichen Position befinden.Gegeben zwei numpy Arrays der gleichen Größe, wie eine Funktion zwei jedes Paar Elemente an der gleichen Position anwenden?

Der folgende Code tut was ich will, aber ich denke, es gibt eine elegantere Lösung.

import numpy as np 
from scipy.stats import binom_test 

h, w = 3, 4 

x=np.random.random_integers(4,9,(h,w)) 
y=np.random.random_integers(4,9,(h,w)) 
result = np.ones((h,w)) 

for row in range(h): 
    result[row,:] = np.array([binom_test(x[row,_], x[row,_]+y[row,_]) for _ in range(w)]) 

print(result) 
+1

Warum kann man nicht einfach Schleife durch beide Arrays gleichzeitig? – Peaceful

Antwort

2

Das erste Argument für stats.binom_test kann eine Anordnung sein, aber das zweite Argument stats.binom_test muss eine ganze Zahl, nicht ein Array sein. So

es sei denn x+y (die als zweite Argumente übergebenen Werte) eine Menge wiederholten Werte enthält, gibt es keine Möglichkeit, die Anzahl der Anrufe an stats.binom_test zu reduzieren. Im Allgemeinen müssen Sie es nur einmal für jedes Element in x und x+y aufrufen.

NumPy hat jedoch eine Hilfsfunktion, np.vectorize, die die Syntax schöner machen kann. np.vectorize gibt eine Funktion zurück, die Arrays als Eingabe nehmen und ein Array als Ausgabe zurückgeben kann. np.vectorize ist hauptsächlich "for convenience, not for performance". Unter der Haube führt es eine for-loop ähnlich wie die, die Sie geschrieben haben. Somit kann die explizite for-loop von

binom_test = np.vectorize(stats.binom_test) 
result = binom_test(x, x+y) 

import numpy as np 
from scipy import stats 
np.random.seed(2016) 
h, w = 3, 4 

x=np.random.random_integers(4,9,(h,w)) 
y=np.random.random_integers(4,9,(h,w)) 

result = np.ones((h,w)) 
for row in range(h): 
    result[row,:] = np.array([stats.binom_test(x[row,_], x[row,_]+y[row,_]) 
           for _ in range(w)]) 

binom_test = np.vectorize(stats.binom_test) 
result2 = binom_test(x, x+y) 

assert np.allclose(result, result2) 
print(result2) 

ergibt

ersetzt werden
[[ 1.   0.75390625 0.77441406 0.60723877] 
[ 1.   0.79052734 0.77441406 0.77441406] 
[ 1.   1.   1.   1.  ]] 
Verwandte Themen