zrozumienie funkcji dstack numpy

Mam problem ze zrozumieniem, co faktycznie robi funkcja numpy. Dokumentacja jest dość skąpa i po prostu mówi:

Stosuj tablice w głębi sekwencji (wzdłuż trzeciej osi).

Pobiera sekwencję tablic i układa je wzdłuż trzeciej osi aby utworzyć jedną tablicę. Przebudowuje tablice podzielone przez dsplit. Jest to prosty sposób na układanie tablic 2D (obrazów) w jeden Tablica 3D do przetwarzania.

Więc albo jestem naprawdę głupi, a znaczenie tego jest oczywiste, albo wydaje mi się, że mam jakieś błędne wyobrażenie o terminach "układanie", "w kolejności", "mądrość głębokości" lub "wzdłuż osi". Jednak odniosłem wrażenie, że dobrze zrozumiałem te terminy w kontekście vstack i hstack.

Weźmy ten przykład:

In [193]: a
Out[193]: 
array([[0, 3],
       [1, 4],
       [2, 5]])
In [194]: b
Out[194]: 
array([[ 6,  9],
       [ 7, 10],
       [ 8, 11]])
In [195]: dstack([a,b])
Out[195]: 
array([[[ 0,  6],
        [ 3,  9]],

       [[ 1,  7],
        [ 4, 10]],

       [[ 2,  8],
        [ 5, 11]]])

Po pierwsze, a i b nie mają trzeciej osi, więc jak miałbym je ułożyć wzdłuż " trzeciej osi " na początek? Po drugie, zakładając a i {[6] } są reprezentacjami obrazów 2D, dlaczego kończę z trzema tablicami 2D w wyniku, w przeciwieństwie do dwóch tablic 2D 'w sekwencji'?

Author: ali_m, 2014-08-04

4 answers

Łatwiej zrozumieć, co np.vstack, np.hstack i np.dstack* wykonaj patrząc na atrybut .shape tablicy wyjściowej.

Używając dwóch przykładowych tablic:

print(a.shape, b.shape)
# (3, 2) (3, 2)
  • np.vstack łączy się wzdłuż pierwszego wymiaru...

    print(np.vstack((a, b)).shape)
    # (6, 2)
    
  • np.hstack łączy się wzdłuż drugiego wymiaru...

    print(np.hstack((a, b)).shape)
    # (3, 4)
    
  • I np.dstack konkatenaty wzdłuż trzeciego wymiaru.

    print(np.dstack((a, b)).shape)
    # (3, 2, 2)
    

Od a i b są dwuwymiarowe, np.dstack rozszerza je wstawiając trzeci wymiar wielkości 1. Jest to równoznaczne z indeksowaniem ich w trzecim wymiarze za pomocą np.newaxis (lub alternatywnie, None) w następujący sposób:

print(a[:, :, np.newaxis].shape)
# (3, 2, 1)

If c = np.dstack((a, b)), then c[:, :, 0] == a and c[:, :, 1] == b.

Możesz zrobić tę samą operację bardziej wyraźnie używając np.concatenate Tak:

print(np.concatenate((a[..., None], b[..., None]), axis=2).shape)
# (3, 2, 2)

* Importowanie całej zawartości modułu do globalnej przestrzeni nazw za pomocą import * jest uważane za złe praktyka z kilku powodów. Idiomatycznym sposobem jest import numpy as np.

 83
Author: ali_m,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:03:08

Niech x == dstack([a, b]). Następnie {[2] } jest identyczne z a, A {[4] } jest identyczne z b. Ogólnie rzecz biorąc, gdy dstacking tablic 2D, dstack generuje wyjście takie, że output[:, :, n] jest identyczne z N-tą tablicą wejściową.

Jeśli stosujemy tablice 3D zamiast 2D:

x = numpy.zeros([2, 2, 3])
y = numpy.ones([2, 2, 4])
z = numpy.dstack([x, y])

Wtedy z[:, :, :3] będzie identyczna z x, a z[:, :, 3:7] będzie identyczna z y.

Jak widzisz, musimy wziąć plasterki wzdłuż trzeciej osi, aby odzyskać wejścia do dstack. Dlatego dstack zachowuje się tak, jak to tak.

 6
Author: user2357112 supports Monica,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-04 10:56:09

Chciałbym spróbować tego wizualnie wyjaśnić (chociaż przyjęta odpowiedź ma sens, Zajęło mi kilka sekund, aby zracjonalizować to w moim umyśle). Jeśli wyobrażamy sobie tablice 2d jako listę list, gdzie pierwsza oś daje jedną z list wewnętrznych, a druga oś podaje wartość z tej listy, to wizualna reprezentacja tablic OP będzie następująca:

a = [
      [0, 3],
      [1, 4],
      [2, 5]
    ]
b = [
      [6,  9],
      [7, 10],
      [8, 11]
    ]
# Shape of each array is [3,2]

Teraz, zgodnie z bieżącą dokumentacją, Funkcja dstack dodaje trzecią oś, co oznacza każda z tablic wygląda tak:

a = [
      [[0], [3]],
      [[1], [4]],
      [[2], [5]]
    ]
b = [
      [[6],  [9]],
      [[7], [10]],
      [[8], [11]]
    ]
# Shape of each array is [3,2,1]

Teraz układanie obu tych tablic w trzecim wymiarze oznacza po prostu, że wynik powinien wyglądać, zgodnie z oczekiwaniami, tak:

dstack([a,b]) = [
                  [[0, 6], [3, 9]],
                  [[1, 7], [4, 10]],
                  [[2, 8], [5, 11]]
                ]
# Shape of the combined array is [3,2,2]
Mam nadzieję, że to pomoże.
 3
Author: goelakash,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-08-25 09:32:04

Ponieważ wspomniałeś o "obrazkach", myślę, że ten przykład byłby przydatny. Jeśli używasz Keras do trenowania sieci splotowej 2D z wejściem x, najlepiej zachować X z wymiarem (#images, dim1ofImage, dim2ofImage).

image1 = np.array([[4,2],[5,5]])
image2 = np.array([[3,1],[6,7]])

image1 = image1.reshape(1,2,2)
image2 = image2.reshape(1,2,2)

X = np.stack((image1,image2),axis=1) 
X
array([[[[4, 2],
         [5, 5]],
        [[3, 1],
        [6, 7]]]])

np.shape(X)         
X = X.reshape((2,2,2))   
X 
array([[[4, 2],
        [5, 5]],
       [[3, 1],
        [6, 7]]])

X[0] # image 1
array([[4, 2],
       [5, 5]])
X[1] # image 2
array([[3, 1],
       [6, 7]])             
 1
Author: datddd,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-20 22:05:14