[PYTHON] Rekursiver Reißverschluss

Einführung

numpy.ndarray hat einen Mechanismus namens Fancy Index. Es ist sehr praktisch, aber die verschachtelte Indexstruktur widerspricht meiner Intuition und ist schwierig zu verwenden. Als Beispiel zitieren wir den folgenden Code aus dem vorherigen Artikel.

import numpy as np

a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]])
a[[0, 1], [2, 2]] #=> [3, 6]

Dies ist der Index zum Extrahieren des Elements "[0, 2]" und des Elements "[1, 2]" ("[0, 1], [2, 2])", aber ich bin "a [[ Ich möchte 0, 2], [1, 2]] `schreiben (Nun, vielleicht ist dies die verschachtelte Reihenfolge, weil ich sie zusammen mit Broadcast und Slice verwenden möchte, aber ich möchte sie intuitiv schreiben). Die Zip-Funktion kann für eine solche Verschachtelung verwendet werden:

a[tuple(zip([0, 2], [1, 2]))] #=> array([3, 6])
#Das Zip-Objekt kann nicht direkt indiziert werden, daher wird es getupft.

Numpy.ndarray kann jedoch ein Tensor höherer Ordnung sein, und ein einfacher zip reicht möglicherweise nicht aus, daher möchte ich eine Funktion, die rekursiv ersetzt.

Implementierung

Da es schwierig ist, die Anforderungen zu verbalisieren, zeigen wir zunächst das Ergebnis von Versuch und Irrtum.

import collections

def deepzip(*x):
  if isinstance(x[0][0], collections.abc.Iterable):
    return zip(*map(lambda y: deepzip(*y), x))
  else:
    return zip(*x)
def invert_index(idx):
  return tuple(deepzip(*idx))

a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]])
a[invert_index(([[0, 2], [1, 2]], [[1, 0], [1, 1]]))] #=> array([[3, 6], [4, 5]])

Da beurteilt wird, ob es "iterierbar" ist, ist es in Ordnung, wenn der Index keine Liste, sondern ein Taple oder "ndarray" ist. Obwohl "x [0] [0]" ekelhaft ist, habe ich die illegale Verarbeitung wie die Tatsache, dass die Tiefen nicht einheitlich sind, weggelassen. Sowohl Eingabe als auch Ausgabe (wenn sie konsistent sind) können beliebig viele Stockwerke sein ...

Bitte lassen Sie mich wissen, ob es ein Muster gibt, das nicht funktioniert, oder ob Sie dies tun sollten.

Recommended Posts

Rekursiver Reißverschluss
Postleitzahl
Python Zip
Rekursive Funktion
Rekursives Darstellungsprotokoll
Geokodierung der Postleitzahl