How does iterating a multidimensional NumPy array work? (With and without nditer)

Note. I'm not sure if this is a duplicate or not. Please let me know if this is (and close the question).

If you have a 1-dimensional NumPy array vector

, then if you write a for loop of the form:

for element in vector :
    print(element)

      

This will print every element of the NumPy array.

If you have a two-dimensional NumPy array matrix

, then if you write a for loop of the form:

for vector in matrix :
    print(vector)

      

The result will print each line of a 2-D NumPy array i.e. it will print one dimensional NumPy arrays, and it will not print each element of the array individually.

However, if you instead write your for loop as:

import numpy
for element in numpy.nditer(matrix) :
     print(element)

      

This will print each element of the 2-D NumPy array.

Question: What happens if you have a 3D NumPy array tensor

?

a. If you write a for loop of the form:

for unknownType in tensor :
     print(unknownType)

      

Will this print NumPy (sub-) composite 2-dimensional arrays from tensor

?

those. for an n-dimensional array NumPy nArray

performs for unknownType in nArray :

iteration of components (n-1) dimensional arrays NumPy (sub-) nArray

?

b. If you write a for loop of the form:

for unknownType in numpy.nditer(tensor) :
    print(unknownType)

      

Will this print items tensor

? Or will it print compound one-dimensional NumPy arrays (sub-) compound two-dimensional NumPy (sub-) arrays tensor

?

those. for an n-dimensional NumPy array nArray

, does it for unknownType in nditer(nArray) :

iterate over the elements nArray

? Or does it iterate over the constituent (n-2) -dimensional NumPy arrays (sub-) constituent (n-1) -dimensional NumPy arrays (sub-) from nArray

?

I don't understand from the name nditer

, since I don't know what "nd" means ("iter" is clearly not suitable for "iteration"). And, presumably, the elements can be thought of as "0-dimensional NumPy arrays", so the examples I have given for 2-dimensional NumPy arrays are ambiguous.

I looked at the np.nditer

documentation
, but to be honest, I didn't understand the examples or what they were trying to demonstrate - - it looks like it was written for programmers (which I don't know) by programmers.

+3


source to share


2 answers


If you just use a loop for

, then iteration is performed along the first dimension, if the array has only one dimension, these will be elements, if it is 2D, these will be strings, if it is 3D, it will be iterating over the plane, ...

However, nditer

is an ND (denotes n-dimensional) iterator. It will iterate over each element of the array. This is (roughly!) Equivalent to for item in your_array.ravel()

(iterating over the flattened "view" of the array). For 1D arrays, it iterates over the elements, for 2D arrays, it iterates first over the elements in the first line, then over the second line, etc.

Note that nditer

much more powerful than it, it can iterate over multiple arrays at once, you can buffer the iteration and much more.




However, with NumPy, you usually don't want to use for

-loop or np.nditer

. There are many "vectorized" operations that do not require manual iteration (in most cases).

+3


source


and)

for x in arr:

iterates over the 1st size of the array.

In [233]: for x in np.arange(24).reshape((2,3,4)):
     ...:     print(x.shape)
     ...:     
(3, 4)
(3, 4)

      

I think of it like for x in list(arr):...

. It splits the array into a list of subarrays.

b)

Difficult to control the iteration depth with nditer

. By default, it iterates at the element level. The man page shows some tricks using buffers and order. but the best way I've seen is to use ndindex

.

ndindex

builds a dummy array of the desired size and multi_index

iterates.

For example, to iterate over the 1st dimensions of a 3-D array:

In [237]: arr = np.arange(24).reshape(2,3,4)
In [240]: for idx in np.ndindex(arr.shape[:2]):
     ...:     print(idx, arr[idx], arr[idx].sum())
     ...:      
(0, 0) [0 1 2 3] 6
(0, 1) [4 5 6 7] 22
(0, 2) [ 8  9 10 11] 38
(1, 0) [12 13 14 15] 54
(1, 1) [16 17 18 19] 70
(1, 2) [20 21 22 23] 86

      



I could do one iteration with

for i in range(2):
    for j in range(3):
         arr[i,j]...

      

or

arr1 = arr.reshape(-1,4)
for ij in range(6):
    arr1[ij]....

      

The speed will be basically the same - all poor compared to array functions that work on the entire 3D array at once, or those that take some parameter axis

.

In [241]: arr.sum(axis=2)
Out[241]: 
array([[ 6, 22, 38],
       [54, 70, 86]])

      


Class for numpy as arrays np.ndarray

. Presumably nditer

named so. nditer

was written as a way to consolidate various which level code c

could iterate over arrays, especially multiple broadcast ones. The function np.nditer

provides access to the level iterator c

. But since the actual iteration is still done in Python code, there is little chance of speed.

+2


source







All Articles