Powiedzmy, że mam małą tablicę RGB-ImageType:

d = [ [ [0, 1, 2],    [3, 4, 5],    [6 ,7 ,8] ], 
      [ [9, 10, 11], [12, 13, 14], [15, 16 ,17] ],
      [ [18,19, 20], [21, 22, 23], [24, 25 ,26] ] ]

Wybieram kilka losowych pikseli R / G lub B przy użyciu random

import random
r = random.sample(range(1, len(d)*len(d[0])*3), 3)
# for example r = [25, 4, 15]

Jak mogę wybrać dane, które chcę?

Jak chcę 25th value in array d dla pierwszego r_value = 25, który odpowiada d[2][2][1], ponieważ jest to 25. wartość.

4
Ludisposed 26 czerwiec 2017, 15:16

5 odpowiedzi

Najlepsza odpowiedź

Jeśli zamierzasz sprawdzić / zmienić tablicę liniowo na podstawie częstego, możesz skonstruować widok liniowy :

d_lin = d.reshape(-1)  # construct a 1d view
d_lin[25]         # access the 25-th element

Lub umieszczenie go w jedną liniową:

d.reshape(-1)[25]  # construct a 1d view

Teraz możesz uzyskać dostęp do dostępu (i modyfikacji) elementów w d_view jako tablica 1D. Dostęp do 25-tej wartości za pomocą d_lin[25]. Nie musisz konstruować nowego widoku za każdym razem, gdy chcesz uzyskać dostęp / modyfikować element: wystarczy ponownie użyć widoku d_lin.

Więcej Meory, C-podobny w inny sposób)). order='F' oznacza, że po raz pierwszy nasilimy w największym wymiarze.

Zaletą widoku (ale może to również prowadzić do niezamienionych zachowań), jest to, że jeśli przypisujesz nową wartość przez d_lin, jak {x1}}, zmieni oryginalną matrycę .

Alternatywy są .flat, lub np.ravel. Więc następujące są nieco równoważne:

d.reshape(-1)[25]
np.ravel(d)[25]
d.flat[25]

Istnieją jednak pewne różnice między reshape(..) a ravel(..) podejście do podejścia flat. Najważniejszym jest fakt, że d.flat robi nie Utwórz pełny widok. Rzeczywiście, jeśli na przykład chcemy przekazać widok na inną funkcję, która oczekuje, że macierzy Numpy, wówczas będzie awarię, na przykład:

>>> d.flat.sum()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'numpy.flatiter' object has no attribute 'sum'
>>> d.reshape(-1).sum()
351
>>> np.ravel(d).sum()
351

Nie jest to problem. Jeśli chcemy ograniczyć liczbę narzędzi (na przykład jako mechanizm ochrony), to faktycznie daje nam nieco więcej zabezpieczeń (chociaż nadal możemy ustawić elementy elementów luzem, a zadzwonić np.sum(..) na an np.sum(..) X1}} obiekt).

3
Willem Van Onsem 26 luty 2018, 15:39

Zakładając, że nie chcesz spłaszczyć tablicy: Jeśli wcześniej znasz rozmiar supliści, możesz go łatwo obliczyć. W swoim przykładzie każdy element głównej listy jest lista dokładnie 3 elementów, każdy element zawierający 3. Aby uzyskać dostęp do n. Możesz zrobić coś takiego

i = n//9 j = (n%9)//3 k = (n%3) element = d[i][j][k]

Dla n=25, otrzymasz i = 2, j = 2, k = 1, tak jak chcesz.

W Python2 możesz (i musisz) używać normalnego operatora / zamiast //

0
Zinki 26 czerwiec 2017, 12:24

Jeśli zależy Ci tylko na wartość, możesz spłaszczyć twoją tablicę i uzyskać do niego bezpośrednio

val = d.flatten()[r]

Jeśli naprawdę chcesz indeks odpowiadający spłaszczonym indeksowi, musisz coś w ten sposób:

ix_2 = r % d.shape[2]
helper_2 = (r - ix_2) / d.shape[2]
ix_1 = helper_2 % d.shape[1]
helper_1 = (helper_2 - ix_1) / d.shape[1]
ix_0 = helper_1 % d.shape[0]

val = d[ix_0, ix_1, ix_2]
-1
Pietro Tortella 26 czerwiec 2017, 12:22

Możesz użyć metody numpy.flatten, tak jak:

a = np.array(d)
d[25] # print 26
0
sagarr 26 czerwiec 2017, 12:23

Co chcesz zrobić, to indeksować jako tablicę płaską lub 1D. Istnieją różne sposoby robienia tego. ravel i reshape(-1) Utwórz widoki 1D, flatten() tworzy kopię 1d.

Najbardziej wydajny jest flat iterator (atrybut, nie metoda):

In [347]: d.flat[25]
Out[347]: 25

(Może być używany w zadaniu, np. d.flat[25]=0.

In [341]: idx = [25, 4, 15]
In [343]: d.flat[idx]
Out[343]: array([25,  4, 15])

Aby dowiedzieć się, co jest indeks 3D, jest narzędzie, unravel_index (i odpowiedni ravel_multi_index)

In [344]: fidx=np.unravel_index(idx,d.shape)
In [345]: fidx
Out[345]: 
(array([2, 0, 1], dtype=int32),
 array([2, 1, 2], dtype=int32),
 array([1, 1, 0], dtype=int32))
In [346]: d[fidx]
Out[346]: array([25,  4, 15])

Ta krotka, indeks dla jednego elementu jest odczytywany "Down", np. (2,2,1).


Na dużej tablicy flat indeksowanie jest rzeczywiście szybsze:

In [362]: dl=np.ones((100,100,100))
In [363]: idx=np.arange(0,1000000,40)
In [364]: fidx=np.unravel_index(idx,dl.shape)
In [365]: timeit x=dl[fidx]
1000 loops, best of 3: 447 µs per loop
In [366]: timeit x=dl.flat[idx]
1000 loops, best of 3: 312 µs per loop
4
Louis Maddox 26 luty 2018, 14:44