Ваш массив:
In [19]: y_true
Out[19]:
array([[[1.],
[0.],
[3.]],
[[5.],
[0.],
[0.]]])
In [20]: y_true.shape
Out[20]: (2, 3, 1)
С последним размером 1, мы можем изменить его
In [21]: y_true.reshape(2,3)
Out[21]:
array([[1., 0., 3.],
[5., 0., 0.]])
Выбор по этому индексу также хорош.
Но вы можете получить доступ ко всем значениям по порядку, просто расправившись / уплощаясь:
In [22]: y_true.ravel()
Out[22]: array([1., 0., 3., 5., 0., 0.])
Или получите 1 итератор:
In [23]: yiter = y_true.flat
In [24]: yiter?
Type: flatiter
String form: <numpy.flatiter object at 0x1fdd200>
Length: 6
File: ~/.local/lib/python3.6/site-packages/numpy/__init__.py
Docstring: <no docstring>
Class docstring:
Flat iterator object to iterate over arrays.
A `flatiter` iterator is returned by ``x.flat`` for any array `x`.
It allows iterating over the array as if it were a 1-D array,
either in a for-loop or by calling its `next` method.
...
Таким образом, вместо создания итератора для каждого измерения мы можем выполнить итерацию для этого плоского:
In [25]: for item in yiter:print(item)
1.0
0.0
3.0
5.0
0.0
0.0
ndenumerate
использует этот плоский итератор и возвращает координаты и значения:
In [26]: list(np.ndenumerate(y_true))
Out[26]:
[((0, 0, 0), 1.0),
((0, 1, 0), 0.0),
((0, 2, 0), 3.0),
((1, 0, 0), 5.0),
((1, 1, 0), 0.0),
((1, 2, 0), 0.0)]
Разновидностью этого является ndindex
:
In [27]: indexs = np.ndindex(y_true.shape)
In [28]: for ijk in indexs:
...: print(ijk, y_true[ijk])
...:
(0, 0, 0) 1.0
(0, 1, 0) 0.0
(0, 2, 0) 3.0
(1, 0, 0) 5.0
(1, 1, 0) 0.0
(1, 2, 0) 0.0
Но там, где это возможно, лучше работать со всем массивом, чем с итерациями. Эти операции с целым массивом выполняют итерацию в скомпилированном коде.