np.nditer return type for reference types

Viewed 459

How can I get the right return type for np.nditer? I need to iterate through ax object here:

fig, ax = plt.subplots(figsize=(16,9), ncols=3, nrows=2)
for col, elem in zip(df.columns[:-1], np.nditer(ax, flags = ['refs_ok'])):
    sns.countplot(x="CLASS", hue=col, data=df, ax=elem)

I know I could have iterated here using the dimension of ax array, but I wonder, if I can make this work. Basically, ax=elem should look like ax=ax[i][j] in iteration. But it turns out they have different types:

print(type(elem))
print(type(ax[0][0]))

returns:

<class 'numpy.ndarray'>
<class 'matplotlib.axes._subplots.AxesSubplot'>
2 Answers

Possibly you want to iterate like

fig, ax = plt.subplots(figsize=(16,9), ncols=3, nrows=2)
for col, elem in zip(df.columns[:-1], ax.flat):
    sns.countplot(x="CLASS", hue=col, data=df, ax=elem)

which is shorter and always makes elem an matplotlib.axes._subplots.AxesSubplot object.

The problem with using a numpy function like this is that it will convert the iterable to an np.ndarray object straight away.

Therefore, your return value will be a slice of this np.ndarray object have a look at the following example

In [472]: list(np.nditer([[None, None], [None, None]], flags = ['refs_ok']))
Out[472]:
[(array(None, dtype=object), array(None, dtype=object)),
 (array(None, dtype=object), array(None, dtype=object))]

In [473]: list(np.nditer([[None, None], [None, None]], flags = ['refs_ok']))[0][0]
Out[473]: array(None, dtype=object)

If you want the raw item from a 0 dimensional numpy array then use the .tolist() method

As you're probably now aware, since you're not iterating numeric types, it doesn't make sense to introduce all this numpy complexity and overhead the correct way to do this is https://stackoverflow.com/a/52316861/4013571

Related