2017-12-18 4 views
1

Zunächst arbeite ich mit Byte-Array (> = 400x400x1000) Bytes. Ich schrieb eine kleine Funktion, die ein mehrdimensionales Array (oder einen Bruchteil von) in ein anderes einfügen kann, indem ein Offset angezeigt wird. Dies funktioniert, wenn das eingebettete Array kleiner ist als das eingebettete Array (Fall A). Andernfalls wird das eingebettete Array abgeschnitten (Fall B).Numpy Array in Array mit Erweiterung des Einbettungsarrays einfügen

Fall A) Das Einfügen eines 3x3 in eine 5x5 Matrix mit Offset 1,1 würde so aussehen.

Fall B) Wenn die Versätze, die Abmessungen der Einbettungsmatrix übersteigt, wird das kleinere Array abgeschnitten. Z.B. Ein (-1, -1) Offset würde dazu führen.

[[ 1. 1. 0. 0. 0.] 
[ 1. 1. 0. 0. 0.] 
[ 0. 0. 0. 0. 0.] 
[ 0. 0. 0. 0. 0.] 
[ 0. 0. 0. 0. 0.]] 

Fall C) nun statt der eingebetteten Array Kürzen, ich möchte die Einbettung Array erweitern (durch Nullen), wenn das eingebettete Array entweder größer als die Einbettung Array ist oder die Offsets erzwingen es (zB Fall B). Gibt es eine clevere Art und Weise mit numpy oder scipy, um das zu lösen?

[[ 1. 1. 1. 0. 0. 0.] 
[ 1. 1. 1. 0. 0. 0.] 
[ 1. 1. 1. 0. 0. 0.] 
[ 0. 0. 0. 0. 0. 0.] 
[ 0. 0. 0. 0. 0. 0.] 
[ 0. 0. 0. 0. 0. 0.]] 

Eigentlich arbeite ich mit 3D-Array, aber der Einfachheit halber habe ich ein Beispiel für 2D-Arrays geschrieben. Aktuelle Quelle:

import numpy as np 
import nibabel as nib 

def addAtPos(mat_bigger, mat_smaller, xyz_coor): 
    size_sm_x, size_sm_y = np.shape(mat_smaller) 
    size_gr_x, size_gr_y = np.shape(mat_bigger) 

    start_gr_x, start_gr_y = xyz_coor 
    start_sm_x, start_sm_y = 0,0 

    end_x, end_y = (start_gr_x + size_sm_x), (start_gr_y + size_sm_y) 

    print(size_sm_x, size_sm_y) 
    print(size_gr_x, size_gr_y) 
    print(end_x, end_y) 

    if start_gr_x < 0: 
     start_sm_x = -start_gr_x 
     start_gr_x = 0 
    if start_gr_y < 0: 
     start_sm_y = -start_gr_y 
     start_gr_y = 0 

    if end_x > size_gr_x: 
     size_sm_x = size_sm_x - (end_x - size_gr_x) 
     end_x = size_gr_x 
    if end_y > size_gr_y: 
     size_sm_y = size_sm_y - (end_y - size_gr_y) 
     end_y = size_gr_y 

    # copy all or a chunk (if offset is small/big enough) of the smaller matrix into the bigger matrix 
    mat_bigger[start_gr_x:end_x, start_gr_y:end_y] = mat_smaller[start_sm_x:size_sm_x, start_sm_y:size_sm_y] 
    return mat_bigger 


a_gr = np.zeros([5,5]) 
a_sm = np.ones([3,3]) 
a_res = addAtPos(a_gr, a_sm, [-2,1]) 
#print (a_gr) 
print (a_res) 
+1

Sie könnten ['numpy.pad'] (https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.pad.html) mit Nullen füllen das größere Array vor dem Einfügen des kleineren in dieses neue gepolsterte Array. – jadsq

+1

'np.pad' ist kompliziert und relativ langsam. Ich würde einfach einen neuen 'mat_bigger' machen, wenn er wachsen muss. Haben Sie keine Angst vor ein paar "Wenn" -Aussagen. Sie werden nur einmal ausgeführt. (Schauen Sie sich das 'np.pad' an, um zu sehen, was einige numpy Funktionen tun, um mehrere Dimensionen und Parameter zu behandeln. Es ist nicht schön.) – hpaulj

+0

Ich löste es wie Sie vorgeschlagen haben. Ich dachte, es gibt vielleicht eine Komfortfunktion. – dgrat

Antwort

0

Eigentlich gibt es einen einfacheren Weg, es zu tun.

Für Ihr erstes Beispiel eines 3x3-Array in einen 5x5 eines eingebetteten Sie es mit so etwas wie zu tun:

A = np.array([[1,1,1], [1,1,1], [1,1,1]]) 
(N, M) = A.shape 

B = np.zeros(shape=(N + 2, M + 2)) 
B[1:-1:, 1:-1] = A 

Durch das Spiel mit Ihnen Aufschneiden eine Teilmenge von A auswählen und legen Sie sie irgendwo in einem kontinuierlichen Teilmenge von B.

Hoffe es hilft! ;-)