2017-03-01 5 views
1

Ich habe einen 2D-Array (es ist tatsächlich sehr groß und eine Ansicht eines anderen Array):Numpy entlang der Achse und Get Index Row

x = np.array([[0, 1, 2], 
      [1, 2, 3], 
      [2, 3, 4], 
      [3, 4, 5]] 
     ) 

Und ich habe eine Funktion, die jede Zeile des Arrays verarbeitet:

def some_func(a): 
    """ 
    Some function that does something funky with a row of numbers 
    """ 
    return [a[2], a[0]] # This is not so funky 

np.apply_along_axis(some_func, 1, x) 

Was ich suche ist eine Möglichkeit, die np.apply_along_axis Funktion aufzurufen, so dass ich den Zugriff auf den Zeilenindex (für die Zeile verarbeitet wird) und dann in der Lage sein, jede Zeile mit dieser Funktion zu verarbeiten:

def some_func(a, idx): 
    """ 
    I plan to use the index for some logic on which columns to 
    return. This is only an example 
    """ 
    return [idx, a[2], a[0]] # This is not so funky 
+0

zip es mit einer Reihe Array? – Divakar

+0

@Divakar Können Sie ein Beispiel geben? Sie können davon ausgehen, dass das 2D-Array eine Ansicht und außergewöhnlich groß ist und eine Kopie keine Lösung darstellt. – slaw

Antwort

0

für einen 2D-Array mit Achse = 1, ist die gleiche wie apply_along_axis Iteration der Reihen des Arrays

In [149]: np.apply_along_axis(some_func, 1, x) 
Out[149]: 
array([[2, 0], 
     [3, 1], 
     [4, 2], 
     [5, 3]]) 
In [151]: np.array([some_func(i) for i in x]) 
Out[151]: 
array([[2, 0], 
     [3, 1], 
     [4, 2], 
     [5, 3]]) 

Für Achse = 0 wir auf x.T iterieren könnten. apply_along_axis ist nützlicher, wenn das Array 3d ist, und wir möchten alle Dimensionen mit Ausnahme von einer iterieren. Dann spart es etwas Langeweile. Aber es ist keine Geschwindigkeitslösung.

Mit Ihrer überarbeiteten Funktion können wir Standard enumerate verwenden sowohl Reihen- und Index zu erhalten:

In [153]: np.array([some_func(v,i) for i,v in enumerate(x)]) 
Out[153]: 
array([[0, 2, 0], 
     [1, 3, 1], 
     [2, 4, 2], 
     [3, 5, 3]]) 

oder mit einem einfachen Bereich Iteration:

In [157]: np.array([some_func(x[i],i) for i in range(x.shape[0])]) 
Out[157]: 
array([[0, 2, 0], 
     [1, 3, 1], 
     [2, 4, 2], 
     [3, 5, 3]]) 

Es gibt verschiedene Tools für die Indizierung bekommen für höhere Dimensionen, Dinge wie ndenumerate und ndindex.

Die schnelle Lösung - Arbeit für alle Zeilen auf einmal:

In [158]: np.column_stack((np.arange(4), x[:,2], x[:,0])) 
Out[158]: 
array([[0, 2, 0], 
     [1, 3, 1], 
     [2, 4, 2], 
     [3, 5, 3]]) 
+0

Gut zu wissen. Ich bin verpflichtet zu fragen, aber gibt es eine Methode, die eine schnelle Lösung ist? – slaw

+0

Ich habe eine ganze Array-Lösung hinzugefügt – hpaulj

0

Hier ist eine alternative Lösung, während für die eigentliche Funktion wartet umgesetzt wurde. Das wird ein bisschen unordentlich. Aber genug, um Ihr Problem im Moment vielleicht anzugehen. :)

# create global variable 
In [247]: global counter 

# Initialize it to your need 
In [248]: counter = 0 

# create your function callback, lambda also could be used 
In [252]: def funct(row): 
    ...:  # reference to global variable created before hand 
    ...:  global counter 
    ...:  counter += 1 # increment the counter 
    ...:  # return something, or else 
    ...:  # will raise a 'NoneType' has no len() exception 
    ...:  return counter 

In [260]: np.apply_along_axis(funct, 1, np.array([[0],[0],[0]])) 
Out[260]: array([1, 2, 3]) 

# revert counter to initial state or the counter will keep raising afterward 
In [261]: counter = 0 

# or you could just delete it if you had no use for it anymore 
In [262]: del counter 

Hoffte, könnte etwas Hilfe für Sie sein :)

Verwandte Themen