blue_note - 11 months ago 50

Python Question

In numpy, the constructors of many objects accept an "array_like" as first argument. Is there a definition of a such object, either as an abstract meta class, or documentation of the methods is should contain??

Answer Source

There is no formal definition of array-like beyond the nearly tautological one -- an array-like is any Python object that `np.array`

can convert to an `ndarray`

.

To go beyond this, you'd need to study the source code.

```
NPY_NO_EXPORT PyObject *
PyArray_FromAny(PyObject *op, PyArray_Descr *newtype, int min_depth,
int max_depth, int flags, PyObject *context)
{
/*
* This is the main code to make a NumPy array from a Python
* Object. It is called from many different places.
*/
PyArrayObject *arr = NULL, *ret;
PyArray_Descr *dtype = NULL;
int ndim = 0;
npy_intp dims[NPY_MAXDIMS];
/* Get either the array or its parameters if it isn't an array */
if (PyArray_GetArrayParamsFromObject(op, newtype,
0, &dtype,
&ndim, dims, &arr, context) < 0) {
Py_XDECREF(newtype);
return NULL;
}
...
```

Particularly interesting is `PyArray_GetArrayParamsFromObject`

, whose comments enumerate the types of objects `np.array`

expects:

```
NPY_NO_EXPORT int
PyArray_GetArrayParamsFromObject(PyObject *op,
PyArray_Descr *requested_dtype,
npy_bool writeable,
PyArray_Descr **out_dtype,
int *out_ndim, npy_intp *out_dims,
PyArrayObject **out_arr, PyObject *context)
{
PyObject *tmp;
/* If op is an array */
/* If op is a NumPy scalar */
/* If op is a Python scalar */
/* If op supports the PEP 3118 buffer interface */
/* If op supports the __array_struct__ or __array_interface__ interface */
/*
* If op supplies the __array__ function.
* The documentation says this should produce a copy, so
* we skip this method if writeable is true, because the intent
* of writeable is to modify the operand.
* XXX: If the implementation is wrong, and/or if actual
* usage requires this behave differently,
* this should be changed!
*/
/* Try to treat op as a list of lists */
}
```

So by studying the source code we can conclude an array-like is

- a NumPy array, or
- a NumPy scalar, or
- a Python scalar, or
- any object which supports the PEP 3118 buffer interface, or
- any object that supports the
`__array_struct__`

or`__array_interface__`

interface, or - any object that supplies the
`__array__`

function, or - any object that can be treated as a list of lists