Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

API: Introducecopy argument fornp.asarray [Array API]#25168

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
ngoldbaum merged 5 commits intonumpy:mainfrommtsokol:asarray-copy-arg
Feb 29, 2024
Merged
Show file tree
Hide file tree
Changes fromall commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 7 additions & 8 deletionsbenchmarks/benchmarks/bench_array_coercion.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -23,33 +23,32 @@ def time_array_dtype_not_kwargs(self, array_like):
np.array(array_like, self.int64)

def time_array_no_copy(self, array_like):
np.array(array_like, copy=False)
np.array(array_like, copy=None)

def time_array_subok(self, array_like):
np.array(array_like, subok=True)

def time_array_all_kwargs(self, array_like):
np.array(array_like, dtype=self.int64, copy=False, order="F",
np.array(array_like, dtype=self.int64, copy=None, order="F",
subok=False, ndmin=2)

def time_asarray(self, array_like):
np.asarray(array_like)

def time_asarray_dtype(self, array_like):
np.array(array_like, dtype=self.int64)
np.asarray(array_like, dtype=self.int64)

def time_asarray_dtype(self, array_like):
np.array(array_like, dtype=self.int64, order="F")
np.asarray(array_like, dtype=self.int64, order="F")

def time_asanyarray(self, array_like):
np.asarray(array_like)
np.asanyarray(array_like)

def time_asanyarray_dtype(self, array_like):
np.array(array_like, dtype=self.int64)
np.asanyarray(array_like, dtype=self.int64)

def time_asanyarray_dtype(self, array_like):
np.array(array_like, dtype=self.int64, order="F")
np.asanyarray(array_like, dtype=self.int64, order="F")

def time_ascontiguousarray(self, array_like):
np.ascontiguousarray(array_like)

8 changes: 8 additions & 0 deletionsdoc/release/upcoming_changes/25168.change.rst
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
New ``copy`` keyword meaning for `numpy.array` and `numpy.asarray`
------------------------------------------------------------------
Now `numpy.array` and `numpy.asarray` support three values for ``copy`` parameter:
* ``None`` - A copy will only be made if it is necessary.
* ``True`` - Always make a copy.
* ``False`` - Never make a copy. If a copy is required a ``ValueError`` is raised.

The meaning of ``False`` changed as it now raises an exception if a copy is needed.
3 changes: 0 additions & 3 deletionsdoc/source/reference/array_api.rst
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -494,9 +494,6 @@ Creation functions differences
* - Feature
- Type
- Notes
* - ``copy`` keyword argument to ``asarray``
- **Compatible**
-

Elementwise functions differences
---------------------------------
Expand Down
37 changes: 24 additions & 13 deletionsdoc/source/reference/arrays.classes.rst
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -305,19 +305,30 @@ NumPy provides several hooks that classes can customize:
.. note:: For ufuncs, it is hoped to eventually deprecate this method in
favour of :func:`__array_ufunc__`.

.. py:method:: class.__array__([dtype])

If defined on an object, should return an ``ndarray``.
This method is called by array-coercion functions like np.array()
if an object implementing this interface is passed to those functions.
Please refer to :ref:`Interoperability with NumPy <basics.interoperability>`
for the protocol hierarchy, of which ``__array__`` is the oldest and least
desirable.

.. note:: If a class (ndarray subclass or not) having the :func:`__array__`
method is used as the output object of an :ref:`ufunc
<ufuncs-output-type>`, results will *not* be written to the object
returned by :func:`__array__`. This practice will return ``TypeError``.
.. py:method:: class.__array__(dtype=None, copy=None)

If defined on an object, should return an ``ndarray``.
This method is called by array-coercion functions like np.array()
if an object implementing this interface is passed to those functions.
The third-party implementations of ``__array__`` must take ``dtype`` and
``copy`` keyword arguments, as ignoring them might break third-party code
or NumPy itself.

- ``dtype`` is a data type of the returned array.
- ``copy`` is an optional boolean that indicates whether a copy should be
returned. For ``True`` a copy should always be made, for ``None`` only
if required (e.g. due to passed ``dtype`` value), and for ``False`` a copy
should never be made (if a copy is still required, an appropriate exception
should be raised).

Please refer to :ref:`Interoperability with NumPy <basics.interoperability>`
for the protocol hierarchy, of which ``__array__`` is the oldest and least
desirable.

.. note:: If a class (ndarray subclass or not) having the :func:`__array__`
method is used as the output object of an :ref:`ufunc
<ufuncs-output-type>`, results will *not* be written to the object
returned by :func:`__array__`. This practice will return ``TypeError``.

.. _matrix-objects:

Expand Down
5 changes: 3 additions & 2 deletionsdoc/source/reference/c-api/array.rst
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -514,8 +514,9 @@ From other objects
PyObject* op, PyArray_Descr* dtype, PyObject* context)

Return an ndarray object from a Python object that exposes the
:obj:`~numpy.class.__array__` method. The :obj:`~numpy.class.__array__`
method can take 0, or 1 argument ``([dtype])``. ``context`` is unused.
:obj:`~numpy.class.__array__` method. The third-party implementations of
:obj:`~numpy.class.__array__` must take ``dtype`` and ``copy`` keyword
arguments. ``context`` is unused.

.. c:function:: PyObject* PyArray_ContiguousFromAny( \
PyObject* op, int typenum, int min_depth, int max_depth)
Expand Down
9 changes: 4 additions & 5 deletionsdoc/source/user/basics.dispatch.rst
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -22,7 +22,7 @@ example that has rather narrow utility but illustrates the concepts involved.
... self._i = value
... def __repr__(self):
... return f"{self.__class__.__name__}(N={self._N}, value={self._i})"
... def __array__(self, dtype=None):
... def __array__(self, dtype=None, copy=None):
... return self._i * np.eye(self._N, dtype=dtype)

Our custom array can be instantiated like:
Expand DownExpand Up@@ -84,7 +84,7 @@ For this example we will only handle the method ``__call__``
... self._i = value
... def __repr__(self):
... return f"{self.__class__.__name__}(N={self._N}, value={self._i})"
... def __array__(self, dtype=None):
... def __array__(self, dtype=None, copy=None):
... return self._i * np.eye(self._N, dtype=dtype)
... def __array_ufunc__(self, ufunc, method, *inputs, **kwargs):
... if method == '__call__':
Expand DownExpand Up@@ -135,7 +135,7 @@ conveniently by inheriting from the mixin
... self._i = value
... def __repr__(self):
... return f"{self.__class__.__name__}(N={self._N}, value={self._i})"
... def __array__(self, dtype=None):
... def __array__(self, dtype=None, copy=None):
... return self._i * np.eye(self._N, dtype=dtype)
... def __array_ufunc__(self, ufunc, method, *inputs, **kwargs):
... if method == '__call__':
Expand DownExpand Up@@ -173,7 +173,7 @@ functions to our custom variants.
... self._i = value
... def __repr__(self):
... return f"{self.__class__.__name__}(N={self._N}, value={self._i})"
... def __array__(self, dtype=None):
... def __array__(self, dtype=None, copy=None):
... return self._i * np.eye(self._N, dtype=dtype)
... def __array_ufunc__(self, ufunc, method, *inputs, **kwargs):
... if method == '__call__':
Expand DownExpand Up@@ -306,4 +306,3 @@ Refer to the `dask source code <https://github.com/dask/dask>`_ and
examples of custom array containers.

See also :doc:`NEP 18<neps:nep-0018-array-function-protocol>`.

14 changes: 12 additions & 2 deletionsdoc/source/user/basics.interoperability.rst
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -75,8 +75,8 @@ relies on the existence of the following attributes or methods:
- ``__array_interface__``: a Python dictionary containing the shape, the
element type, and optionally, the data buffer address and the strides of an
array-like object;
- ``__array__()``: a method returning the NumPy ndarray view of an array-like
object;
- ``__array__()``: a method returning the NumPy ndarraycopy or aview of an
array-likeobject;

The ``__array_interface__`` attribute can be inspected directly:

Expand DownExpand Up@@ -125,6 +125,16 @@ new ndarray object. This is not optimal, as coercing arrays into ndarrays may
cause performance problems or create the need for copies and loss of metadata,
as the original object and any attributes/behavior it may have had, is lost.

The signature of the method should be ``__array__(self, dtype=None, copy=None)``.
If a passed ``dtype`` isn't ``None`` and different than the object's data type,
a casting should happen to a specified type. If ``copy`` is ``None``, a copy
should be made only if ``dtype`` argument enforces it. For ``copy=True``, a copy
should always be made, where ``copy=False`` should raise an exception if a copy
is needed.

If a class implements the old signature ``__array__(self)``, for ``np.array(a)``
a warning will be raised saying that ``dtype`` and ``copy`` arguments are missing.

To see an example of a custom array implementation including the use of
``__array__()``, see :ref:`basics.dispatch`.

Expand Down
12 changes: 8 additions & 4 deletionsnumpy/__init__.pyi
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -1464,9 +1464,13 @@ class ndarray(_ArrayOrScalarCommon, Generic[_ShapeType, _DType_co]):
def __class_getitem__(self, item: Any) -> GenericAlias: ...

@overload
def __array__(self, dtype: None = ..., /) -> ndarray[Any, _DType_co]: ...
def __array__(
self, dtype: None = ..., /, *, copy: None | bool = ...
) -> ndarray[Any, _DType_co]: ...
@overload
def __array__(self, dtype: _DType, /) -> ndarray[Any, _DType]: ...
def __array__(
self, dtype: _DType, /, *, copy: None | bool = ...
) -> ndarray[Any, _DType]: ...

def __array_ufunc__(
self,
Expand DownExpand Up@@ -3715,9 +3719,9 @@ class poly1d:
__hash__: ClassVar[None] # type: ignore

@overload
def __array__(self, t: None = ...) -> NDArray[Any]: ...
def __array__(self, t: None = ..., copy: None | bool = ...) -> NDArray[Any]: ...
@overload
def __array__(self, t: _DType) -> ndarray[Any, _DType]: ...
def __array__(self, t: _DType, copy: None | bool = ...) -> ndarray[Any, _DType]: ...

@overload
def __call__(self, val: _ScalarLike_co) -> Any: ...
Expand Down
31 changes: 22 additions & 9 deletionsnumpy/_core/_add_newdocs.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -807,12 +807,14 @@
a default ``dtype`` that can represent the values (by applying promotion
rules when necessary.)
copy : bool, optional
Iftrue (default), then the array data is copied.Otherwise, a copy
will only be made if ``__array__`` returns a copy, if obj is a nested
sequence, or if a copy is needed to satisfy any of the other
If``True`` (default), then the array data is copied.If ``None``,
a copywill only be made if ``__array__`` returns a copy, if obj is
a nestedsequence, or if a copy is needed to satisfy any of the other
requirements (``dtype``, ``order``, etc.). Note that any copy of
the data is shallow, i.e., for arrays with object dtype, the new
array will point to the same objects. See Examples for `ndarray.copy`.
For ``False`` it raises a ``ValueError`` if a copy cannot be avoided.
Default: ``True``.
order : {'K', 'A', 'C', 'F'}, optional
Specify the memory layout of the array. If object is not an array, the
newly created array will be in C order (row major) unless 'F' is
Expand All@@ -828,7 +830,7 @@
'F' F order F order
===== ========= ===================================================

When ``copy=False`` and a copy is made for other reasons, the result is
When ``copy=None`` and a copy is made for other reasons, the result is
the same as if ``copy=True``, with some exceptions for 'A', see the
Notes section. The default order is 'K'.
subok : bool, optional
Expand DownExpand Up@@ -915,7 +917,7 @@

add_newdoc('numpy._core.multiarray', 'asarray',
"""
asarray(a, dtype=None, order=None, *, device=None, like=None)
asarray(a, dtype=None, order=None, *, device=None,copy=None,like=None)

Convert the input to an array.

Expand All@@ -939,6 +941,13 @@
For Array-API interoperability only, so must be ``"cpu"`` if passed.

.. versionadded:: 2.0.0
copy : bool, optional
If ``True``, then the object is copied. If ``None`` then the object is
copied only if needed, i.e. if ``__array__`` returns a copy, if obj
is a nested sequence, or if a copy is needed to satisfy any of
the other requirements (``dtype``, ``order``, etc.).
For ``False`` it raises a ``ValueError`` if a copy cannot be avoided.
Default: ``None``.
${ARRAY_FUNCTION_LIKE}

.. versionadded:: 1.20.0
Expand DownExpand Up@@ -2934,11 +2943,15 @@

add_newdoc('numpy._core.multiarray', 'ndarray', ('__array__',
"""
a.__array__([dtype], /)
a.__array__([dtype], /, *, copy=None)

Returns either a new reference to self if dtype is not given or a new array
of provided data type if dtype is different from the current dtype of the
array.
For ``dtype`` parameter it returns either a new reference to self if
``dtype`` is not given or a new array of provided data type if ``dtype``
is different from the current data type of the array.
For ``copy`` parameter it returns a new reference to self if
``copy=False`` or ``copy=None`` and copying isn't enforced by ``dtype``
parameter. The method returns a new array for ``copy=True``, regardless of
``dtype`` parameter.

"""))

Expand Down
2 changes: 1 addition & 1 deletionnumpy/_core/_asarray.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -123,7 +123,7 @@ def require(a, dtype=None, requirements=None, *, like=None):
order = 'C'
requirements.remove('C')

arr = array(a, dtype=dtype, order=order, copy=False, subok=subok)
arr = array(a, dtype=dtype, order=order, copy=None, subok=subok)

for prop in requirements:
if not arr.flags[prop]:
Expand Down
2 changes: 1 addition & 1 deletionnumpy/_core/defchararray.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -1148,7 +1148,7 @@ class adds the following functionality:

copy : bool, optional
If true (default), then the object is copied. Otherwise, a copy
will only be made if __array__ returns a copy, if obj is a
will only be made if``__array__`` returns a copy, if obj is a
nested sequence, or if a copy is needed to satisfy any of the other
requirements (`itemsize`, unicode, `order`, etc.).

Expand Down
2 changes: 1 addition & 1 deletionnumpy/_core/function_base.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -300,7 +300,7 @@ def logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None,
"""
ndmax = np.broadcast(start, stop, base).ndim
start, stop, base = (
np.array(a, copy=False, subok=True, ndmin=ndmax)
np.array(a, copy=None, subok=True, ndmin=ndmax)
for a in (start, stop, base)
)
y = linspace(start, stop, num=num, endpoint=endpoint, axis=axis)
Expand Down
14 changes: 9 additions & 5 deletionsnumpy/_core/multiarray.pyi
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -181,7 +181,7 @@ def array(
object: _ArrayType,
dtype: None = ...,
*,
copy: bool | _CopyMode = ...,
copy:None |bool | _CopyMode = ...,
order: _OrderKACF = ...,
subok: L[True],
ndmin: int = ...,
Expand All@@ -192,7 +192,7 @@ def array(
object: _ArrayLike[_SCT],
dtype: None = ...,
*,
copy: bool | _CopyMode = ...,
copy:None |bool | _CopyMode = ...,
order: _OrderKACF = ...,
subok: bool = ...,
ndmin: int = ...,
Expand All@@ -203,7 +203,7 @@ def array(
object: object,
dtype: None = ...,
*,
copy: bool | _CopyMode = ...,
copy:None |bool | _CopyMode = ...,
order: _OrderKACF = ...,
subok: bool = ...,
ndmin: int = ...,
Expand All@@ -214,7 +214,7 @@ def array(
object: Any,
dtype: _DTypeLike[_SCT],
*,
copy: bool | _CopyMode = ...,
copy:None |bool | _CopyMode = ...,
order: _OrderKACF = ...,
subok: bool = ...,
ndmin: int = ...,
Expand All@@ -225,7 +225,7 @@ def array(
object: Any,
dtype: DTypeLike,
*,
copy: bool | _CopyMode = ...,
copy:None |bool | _CopyMode = ...,
order: _OrderKACF = ...,
subok: bool = ...,
ndmin: int = ...,
Expand DownExpand Up@@ -485,6 +485,7 @@ def asarray(
order: _OrderKACF = ...,
*,
device: None | L["cpu"] = ...,
copy: None | bool = ...,
like: None | _SupportsArrayFunc = ...,
) -> NDArray[_SCT]: ...
@overload
Expand All@@ -494,6 +495,7 @@ def asarray(
order: _OrderKACF = ...,
*,
device: None | L["cpu"] = ...,
copy: None | bool = ...,
like: None | _SupportsArrayFunc = ...,
) -> NDArray[Any]: ...
@overload
Expand All@@ -503,6 +505,7 @@ def asarray(
order: _OrderKACF = ...,
*,
device: None | L["cpu"] = ...,
copy: None | bool = ...,
like: None | _SupportsArrayFunc = ...,
) -> NDArray[_SCT]: ...
@overload
Expand All@@ -512,6 +515,7 @@ def asarray(
order: _OrderKACF = ...,
*,
device: None | L["cpu"] = ...,
copy: None | bool = ...,
like: None | _SupportsArrayFunc = ...,
) -> NDArray[Any]: ...

Expand Down
2 changes: 1 addition & 1 deletionnumpy/_core/numeric.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -868,7 +868,7 @@ def convolve(a, v, mode='full'):
array([2.5])

"""
a, v = array(a, copy=False, ndmin=1), array(v, copy=False, ndmin=1)
a, v = array(a, copy=None, ndmin=1), array(v, copy=None, ndmin=1)
if (len(v) > len(a)):
a, v = v, a
if len(a) == 0:
Expand Down
Loading

[8]ページ先頭

©2009-2025 Movatter.jp