__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)
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
@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. –
@hpaulj and behzad.nouri: Czy sugerowałbym, aby zgłosić o tym raport o błędzie? –