2015-02-22 18 views

Odpowiedz

5

Wewnętrznie numpy oblicza wyniki w jeden wymiarowej tablicy, ale potem wraca krotki, które są widoki z krokiem na tej samej tablicy, one for each dimension;

na przykład, jeśli tablica jest tak:

>>> a 
array([[0, 1, 0], 
     [3, 0, 5]]) 

wewnętrznie NumPy najpierw oblicza

>>> i 
array([0, 1, 1, 0, 1, 2]) 

gdzie i[2 * k] i i[2 * k + 1] są indeksy k -tym niezerowej wartości; ale, to wynik, który jest zwracany jest:

>>> (i[::2], i[1::2]) 
(array([0, 1, 1]), array([1, 0, 2])) 

, gdy tworzy go zobaczyć passes 0 as the flags argument. Zatem zapisywalna flaga jest rozbrojona.

Gdy tablica wejściowa jest jednowymiarowa, it takes a short-cut i dlatego flagi są ustawione inaczej.

+0

To tylko wynik tego, jak tworzona jest krotka, a nie coś, o czym zwykle powinien wiedzieć użytkownik końcowy. Użytkownik końcowy zazwyczaj nie próbuje modyfikować wyników. – hpaulj

+0

@hpaulj być może! z tego kawałka kodu, jeśli czegoś nie brakuje, nie widzę powodu, dla którego nie powinien mieć zapisywalnej flagi. –

+0

@hpaulj and behzad.nouri: Czy sugerowałbym, aby zgłosić o tym raport o błędzie? –

1

__array_interface__ daje dowody, że elementy b przedstawiają widoki:

In [335]: b[0].__array_interface__ 
Out[335]: 
{'shape': (10,), 
'typestr': '<i4', 
'strides': (8,), 
'version': 3, 
'descr': [('', '<i4')], 
'data': (145873656, True)} 

In [336]: b[1].__array_interface__ 
Out[336]: 
{'shape': (10,), 
'typestr': '<i4', 
'strides': (8,), 
'version': 3, 
'descr': [('', '<i4')], 
'data': (145873660, True)} 

Kształt i kroki są takie same. Wskaźnik danych różni się o 4 bajty. Tego można się spodziewać po widokach generowanych przez (i[::2], i[1::2]). Krok (8,) oznacza każdą inną liczbę całkowitą.

i wewnętrzny 2d ret tablica może być „odtwarzane” z as_strided:

In [362]: np.lib.stride_tricks.as_strided(b[0],(10,2),(8,4)) 
Out[362]: 
array([[0, 0], 
     [0, 1], 
     [1, 0], 
     [1, 1], 
     [2, 0], 
     [2, 1], 
     [3, 0], 
     [3, 1], 
     [4, 0], 
     [4, 1]]) 

Postać krotka jest najbardziej przydatny do zastosowania jako wskaźnika. Wciąż jest interesujące wiedzieć, że podstawą tej krotki jest tablica 2d.


to Python repliką niezerową funkcji (ndim> 1 przypadek) C. Jest to ostatni krok, napisany jako tuple(ret.T), gdzie generowane są tylko widoki tylko do odczytu. Zgodnie z oczekiwaniami jest to znacznie wolniejsze niż kod C. Powinno to być interesujące ćwiczenie adaptacyjne cython.

def nonzero(a): 
    nnz = np.count_nonzero(a) 
    ndim = a.ndim 
    ret = np.zeros((nnz, ndim), dtype=np.intp) 
    it = np.nditer(a,flags=['multi_index', 'zerosize_ok', 'refs_ok'], 
      op_flags=['readonly']) 
    n = 0 
    while not it.finished: 
     if it.value!=0: 
      ret[n] = it.multi_index 
      n += 1 
     it.iternext() 
    # tuple(ret[:,i] for i in range(ndim)) 
    return tuple(ret.T) 
Powiązane problemy