Alexander Pozdneev
Alexander Pozdneev

Reputation: 1389

Why does NumPy return "no fill-function for data-type" when an array is created with dtype=bool?

The np.fromfunction(lambda i, j: i == j, (3, 3), dtype=int) call works perfectly and results in an array for which .dtype returns dtype('bool').

However, if I explicitly specify dtype=bool in the function call, I get the following error:

ValueError: no fill-function for data-type.

What is the reason for that?

Upvotes: 0

Views: 129

Answers (2)

hpaulj
hpaulj

Reputation: 231385

fromfunction just does:

args = indices(shape, dtype=dtype)
return function(*args, **kwargs)

dtype is passed to indices. It has nothing to do with the result returned by your function.

np.indices does

for i, dim in enumerate(dimensions):
    idx = arange(dim, dtype=dtype).reshape(
        shape[:i] + (dim,) + shape[i+1:]
    )

In [354]: np.indices((3,3))
Out[354]: 
array([[[0, 0, 0],
        [1, 1, 1],
        [2, 2, 2]],

       [[0, 1, 2],
        [0, 1, 2],
        [0, 1, 2]]])
In [355]: np.indices((3,3),dtype=bool)
Traceback (most recent call last):
  File "<ipython-input-355-75b7ff9469d4>", line 1, in <module>
    np.indices((3,3),dtype=bool)
  File "/usr/local/lib/python3.8/dist-packages/numpy/core/numeric.py", line 1772, in indices
    idx = arange(dim, dtype=dtype).reshape(
ValueError: no fill-function for data-type.

See the error in arange?

Making a matrix like [354] doesn't make sense for bool, does it?

Look again at the fromfunction docs:

dtype : data-type, optional
    Data-type of the coordinate arrays passed to `function`.
    By default, `dtype` is float.

dtype is for the coordinates passed to function, not the result of function.

edit

At the risk of being redundant, here's the full traceback when using your code

Traceback (most recent call last):
  File "<ipython-input-358-dfc87db48bcc>", line 1, in <module>
    np.fromfunction(lambda i, j: i == j, (3, 3), dtype=bool)
  File "/usr/local/lib/python3.8/dist-packages/numpy/core/numeric.py", line 1845, in fromfunction
    args = indices(shape, dtype=dtype)
  File "/usr/local/lib/python3.8/dist-packages/numpy/core/numeric.py", line 1772, in indices
    idx = arange(dim, dtype=dtype).reshape(
ValueError: no fill-function for data-type.

Pay attention to each calling level - fromfunction, indices, arange.

again

fromfunction gives the illusion of doing something significant, but as the initial quote shows, it just generates a indices and passes them to your function.

Your example could just as easily be done with a pair of broadcasted arange:

In [359]: np.fromfunction(lambda i, j: i == j, (3, 3), dtype=int)
Out[359]: 
array([[ True, False, False],
       [False,  True, False],
       [False, False,  True]])
In [360]: np.arange(3)[:,None]==np.arange(3)
Out[360]: 
array([[ True, False, False],
       [False,  True, False],
       [False, False,  True]])

Upvotes: 1

Dinari
Dinari

Reputation: 2557

It needs to construct the coordinates for the (3,3) array, this cant be done when the array is of dtype=bool.

Under the hood it calls np.arange(...,dtype=bool), which cant be done, resulting in this exact error.

Upvotes: 1

Related Questions