numpy: formele definitie van “array_like” objecten?

In numpy accepteren de constructeurs van veel objecten een “array_like” als eerste argument. Is er een definitie van een dergelijk object, hetzij als een abstracte metaklasse, of documentatie van de methoden die het zou moeten bevatten??


Antwoord 1, autoriteit 100%

Het blijkt dat bijna alles technisch gezien een array-achtig is. “Array-achtig” is meer een verklaring van hoe de invoer zal worden geïnterpreteerd dan een beperking van wat de invoer kan zijn; als een parameter is gedocumenteerd als array-achtig, zal NumPy proberen deze als een array te interpreteren.

Er is geen formele definitie van array-achtig buiten de bijna tautologische— een array-achtig is elk Python-object dat np.arraykan converteren naar een ndarray. Om verder te gaan, moet je de broncode.

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;
    }
    ...

Bijzonder interessant is PyArray_GetArrayParamsFromObject, wiens opmerkingen de typen objecten opsommen die np.arrayverwacht:

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 */
    /* Anything can be viewed as an object, unless it needs to be writeable */
}

Dus door de broncode te bestuderen, kunnen we concluderen dat een array-achtig is


Antwoord 2, autoriteit 12%

De term “array-achtig”wordt gebruikt in NumPy, verwijzend naar alles dat als eerste parameter kan worden doorgegeven aan numpy.array()om een ​​array () te maken.

Volgens de Numpy-document:

Over het algemeen kunnen numerieke gegevens die in een array-achtige structuur in Python zijn gerangschikt, worden geconverteerd naar arrays met behulp van de functie array(). De meest voor de hand liggende voorbeelden zijn lijsten en tupels. Zie de documentatie voor array() voor details over het gebruik ervan. Sommige objecten ondersteunen mogelijk het array-protocol en staan ​​op deze manier conversie naar arrays toe. Een eenvoudige manier om erachter te komen of het object kan worden geconverteerd naar een numpy-array met behulp van array() is door het eenvoudig interactief te proberen en te kijken of het werkt! (De Python-manier).

Lees voor meer informatie:


Antwoord 3, autoriteit 6%

Het is maar een concept, en er is een officiële verklaring (in Numpy Glossary)hierover naast de uitleg in Gebruikershandleidinggedeeltegenoemd in andere antwoorden:

array_like

Elke reeks die kan worden geïnterpreteerd als een ndarray. Dit bevat
geneste lijsten, tupels, scalairen en bestaande arrays.

zodat zelfs scalaire waarden in aanmerking kunnen worden genomen, net als np.array(1024).


Antwoord 4, autoriteit 6%

NumPy 1.21 introduceert numpy.typing.ArrayLike.


Oorspronkelijk als volgt gedefinieerd in deze toezegging:

class _SupportsArray(Protocol):
    @overload
    def __array__(self, __dtype: DtypeLike = ...) -> ndarray: ...
    @overload
    def __array__(self, dtype: DtypeLike = ...) -> ndarray: ...
ArrayLike = Union[bool, int, float, complex, _SupportsArray, Sequence]

Een recentere definitie van ArrayLikeis echter te vinden in numpy/typing/_array_like.py:

_ArrayLike = Union[
    _NestedSequence[_SupportsArray[_DType]],
    _NestedSequence[_T],
]
ArrayLike = Union[
    _RecursiveSequence,
    _ArrayLike[
        "dtype[Any]",
        Union[bool, int, float, complex, str, bytes]
    ],
]

Antwoord 5

Ik heb dit als reactie geplaatst, maar ik denk dat ik het ook als antwoord zal plaatsen.

Het blijkt dat het concept van “array-achtig” minder een abstracte basisklasse of protocol is en meer over HOE de array-gelijkenis van verschillende objecten zal worden behandeld. Dat wil zeggen, array-achtig is een verklaring over wat er met het object zal worden gedaan wanneer het wordt geleverd als een array-achtig argument. Maar zo ongeveer elk object kan worden geleverd als een array-achtig argument.

Voor veel objecten wordt array-gelijkenis ongeveer hetzelfde behandeld als een iterable. Dit geldt voor sequentie-objecten:

>>> x=[1,2,3]
>>> a = np.array(x)
>>> a[0]
1

Numpy behandelt itereerbare objecten in het algemeen (indien geleverd als een array-achtig argument) echter niet op dezelfde manier. In plaats daarvan behandelt het array-achtige objecten als genest of atomair, afhankelijk van het type.

Hier zijn een paar voorbeelden van objecten die itereerbaar zijn (een idee dat nauw verwant klinkt aan array-achtig, maar heel anders is), maar dat numpy behandelt als atomair.

  • strings (strobjecten)
  • woordenboeken/toewijzingen
  • sets
  • iterators
  • buffers/bestandshandlers

De array()-fabriek behandelt al deze als atomaire (dwz niet geneste) waarden. Kortom: array-achtig is op geen enkele manier een synoniem voor typing.Iterable.

Other episodes