Sie können dies erreichen, indem eine dritte Reihe von dtype uint8 Erstellung, plus eine Bool Array (die zusammen mehr Speichereffizienz sind, dass eine Uint16-Array).
np.putmask
ist nützlich, um ein Temp-Array zu vermeiden.
a = np.array([100, 200, 250], dtype=np.uint8)
b = np.array([50, 50, 50], dtype=np.uint8)
c = 255 - b # a temp uint8 array here
np.putmask(a, c < a, c) # a temp bool array here
a += b
Wie jedoch @moarningsun korrekt ausführt, ein bool Array nimmt die die gleiche Menge an Speicher als uint8 Array, so ist dies nicht unbedingt hilfreich. Es ist möglich, dies zu lösen, durch die Vermeidung von mehr als ein temporären Array mit zu einem bestimmten Zeitpunkt:
a = np.array([100, 200, 250], dtype=np.uint8)
b = np.array([50, 50, 50], dtype=np.uint8)
b = 255 - b # old b is gone shortly after new array is created
np.putmask(a, b < a, b) # a temp bool array here, then it's gone
a += 255 - b # a temp array here, then it's gone
Dieser Ansatz handelt Speicherverbrauch für die CPU.
Ein weiterer Ansatz ist es, vorberechnen alle möglichen Ergebnisse, die O (1) zusätzliche Speicher (dh unabhängig von der Größe des Arrays) sind:
c = np.clip(np.arange(256) + np.arange(256)[..., np.newaxis], 0, 255).astype(np.uint8)
c
=> array([[ 0, 1, 2, ..., 253, 254, 255],
[ 1, 2, 3, ..., 254, 255, 255],
[ 2, 3, 4, ..., 255, 255, 255],
...,
[253, 254, 255, ..., 255, 255, 255],
[254, 255, 255, ..., 255, 255, 255],
[255, 255, 255, ..., 255, 255, 255]], dtype=uint8)
c[a,b]
=> array([150, 250, 255], dtype=uint8)
Dieser Ansatz ist der Speicher -effizient, wenn Ihre Arrays sehr groß sind. Wiederum ist es in der Verarbeitungszeit teuer, weil es die superschnellen Ganzzahladditionen durch die langsamere 2dim-Arrayindizierung ersetzt.
ERKLÄRUNG DER SO GEHTS
Bau des c
Array macht über die Verwendung eines numpy Rundfunk Trick. Hinzufügen eines Arrays von Form (N,)
und Array von Form (1,N)
senden beide zu (N,N)
-Like, so ist das Ergebnis ein NxN-Array aller möglichen Summen. Dann schneiden wir es ab. Wir erhalten ein 2dim-Array, das erfüllt: c[i,j]=min(i+j,255)
für jeden i, j.
Dann, was übrig bleibt, ist mit phantastischen Indizierung der Greifer die richtigen Werte.Arbeiten mit dem Eingang, den Sie zur Verfügung gestellt, greifen wir auf:
c[([100, 200, 250] , [50, 50, 50])]
Der erste Index-Array zum ersten dim bezieht und die zweite auf dem zweiten dim. Somit ist das Ergebnis ein Array mit der gleichen Form wie die Indexarrays ((N,)
), bestehend aus den Werten [ c[100,50] , c[200,50] , c[250,50] ]
.
Ich wusste nichts über 'Putmask', danke dafür! Mit dieser Funktion denke ich, dass "a + = b" gefolgt von "np.putmask (a, a
@moarningsun Ich denke du bist richtig. Allerdings hängt es vom Überlaufen ab, mit dem ich mich persönlich nicht wohl fühle ... – shx2
@moarningsun Warum hast du deine Antwort gelöscht? Ich denke, es ist eine anständige Antwort und es funktioniert – shx2