2017-12-28 10 views
-4

Ich muss eine generische Operation auf die Elemente von einigen np 2D-Arrays (A, B, C) implementieren. Im PseudocodeVermeiden verschachtelt mit numpy Arrays

for i in A.height: 
    for j in A.width: 
     A[i,j] = f(B[i,j],C[i,j]) 

wobei f() die Bits der beiden Variablen durch struct.pack Verketten(), struct.unpack()

  x = struct.pack('2B', B[i, j], C[i, j]) 
      y = struct.unpack('H', x) 

Dieser Code eine wirklich lange dauert Zeit zur Ausführung (0,25 Sekunden für 640 * 480 Matrizen ... vielleicht ist das normal, aber ich könnte etwas schneller verwenden), also frage ich mich, ob jemand mir eine pythische Art vorschlagen könnte, das gleiche Ergebnis zu erreichen, das auch die Leistung verbessern könnte

+2

Hängt davon ab, was 'f()' tut. Sie könnten versuchen, Threads oder Multiprocessing zu verwenden. – Harvey

+3

Nicht wirklich sicher, wie Sie erwarten, dass jemand antwortet, ohne zu wissen, was 'f' tut, wie groß Ihre Daten sind oder was" wirklich lange Zeit für die Ausführung "bedeutet. – excaza

+2

Können Sie 'f' ändern, um [Broadcasting] (http://scipy.github.io/old-wiki/pages/EricsBroadcastingDoc) zu nutzen? –

Antwort

0

Hängt davon ab, was 'f' tut ... Nicht sicher, ob du das meinst

b = np.arange(3*4).reshape(3,4) 
c = np.arange(3*4).reshape(3,4)[::-1] 

b 
array([[ 0, 1, 2, 3], 
     [ 4, 5, 6, 7], 
     [ 8, 9, 10, 11]]) 

c 
array([[ 8, 9, 10, 11], 
     [ 4, 5, 6, 7], 
     [ 0, 1, 2, 3]]) 

def f(b, c): 
    """some function""" 
    a = b + c 
    return a 

a = f(b, c) 
a 
array([[ 8, 10, 12, 14], 
     [ 8, 10, 12, 14], 
     [ 8, 10, 12, 14]]) 
1

Ihre Funktion:

In [310]: def foo(a,b): 
    ...:  x = struct.pack('2B', a,b) 
    ...:  return struct.unpack('H',x)[0] 

np.vectorize ist eine bequeme Art und Weise des Rundfunk Arrays. Es übergibt skalare Werte an die Funktionen. Es ist die Geschwindigkeit nicht den Code oben (frompyfunc Zusammenhang kann eine 2-facher Geschwindigkeit nach oben relativ zur Ebene Iteration geben)

In [311]: fv = np.vectorize(foo) 
In [312]: fv(np.arange(5)[:,None],np.arange(10)) 
Out[312]: 
array([[ 0, 256, 512, 768, 1024, 1280, 1536, 1792, 2048, 2304], 
     [ 1, 257, 513, 769, 1025, 1281, 1537, 1793, 2049, 2305], 
     [ 2, 258, 514, 770, 1026, 1282, 1538, 1794, 2050, 2306], 
     [ 3, 259, 515, 771, 1027, 1283, 1539, 1795, 2051, 2307], 
     [ 4, 260, 516, 772, 1028, 1284, 1540, 1796, 2052, 2308]]) 

ich diese Werte mit einem einfachen mathematischen Ausdruck in dem gleichen Arrays replizieren kann:

In [313]: np.arange(5)[:,None]+np.arange(10)*256 
Out[313]: 
array([[ 0, 256, 512, 768, 1024, 1280, 1536, 1792, 2048, 2304], 
     [ 1, 257, 513, 769, 1025, 1281, 1537, 1793, 2049, 2305], 
     [ 2, 258, 514, 770, 1026, 1282, 1538, 1794, 2050, 2306], 
     [ 3, 259, 515, 771, 1027, 1283, 1539, 1795, 2051, 2307], 
     [ 4, 260, 516, 772, 1028, 1284, 1540, 1796, 2052, 2308]]) 

Dies funktioniert wahrscheinlich nur für begrenzte Wertebereiche, aber es gibt eine Vorstellung davon, wie Sie Berechnungen in numpy richtig 'vektorisieren' können.