diff --git a/src/awkward/_v2/operations/structure/ak_full_like.py b/src/awkward/_v2/operations/structure/ak_full_like.py index 1bb11878e1..d4a67a0700 100644 --- a/src/awkward/_v2/operations/structure/ak_full_like.py +++ b/src/awkward/_v2/operations/structure/ak_full_like.py @@ -1,6 +1,6 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE - +from awkward._v2.operations.structure.ak_zeros_like import _ZEROS import awkward as ak np = ak.nplike.NumpyMetadata.instance() @@ -8,166 +8,164 @@ # @ak._v2._connect.numpy.implements("full_like") def full_like(array, fill_value, highlevel=True, behavior=None, dtype=None): - raise NotImplementedError - - -# """ -# Args: -# array: Array to use as a model for a replacement that contains only -# `fill_value`. -# fill_value: Value to fill new new array with. -# highlevel (bool, default is True): If True, return an #ak.Array; -# otherwise, return a low-level #ak.layout.Content subclass. -# behavior (None or dict): Custom #ak.behavior for the output array, if -# high-level. -# dtype (None or type): Overrides the data type of the result. - -# This is the equivalent of NumPy's `np.full_like` for Awkward Arrays. - -# Although it's possible to produce an array of `fill_value` with the structure -# of an `array` using #ak.broadcast_arrays: - -# >>> array = ak.Array([[1, 2, 3], [], [4, 5]]) -# >>> ak.broadcast_arrays(array, 1) -# [, -# ] -# >>> ak.broadcast_arrays(array, 1.0) -# [, -# ] - -# Such a technique takes its type from the scalar (`1` or `1.0`), rather than -# the array. This function gets all types from the array, which might not be -# the same in all parts of the structure. - -# Here is an extreme example: - -# >>> array = ak.Array([ -# ... [{"x": 0.0, "y": []}, -# ... {"x": 1.1, "y": [1]}, -# ... {"x": 2.2, "y": [1, 2]}], -# ... [], -# ... [{"x": 3.3, "y": [1, 2, None, 3]}, -# ... False, -# ... False, -# ... True, -# ... {"x": 4.4, "y": [1, 2, None, 3, 4]}]]) -# >>> ak.to_list(ak.full_like(array, 12.3)) -# [[{"x": 12.3, "y": []}, -# {"x": 12.3, "y": [12]}, -# {"x": 12.3, "y": [12, 12]}], -# [], -# [{"x": 12.3, "y": [12, 12, None, 12]}, -# True, -# True, -# True, -# {"x": 12.3, "y": [12, 12, None, 12, 12]}]] - -# The `"x"` values get filled in with `12.3` because they retain their type -# (`float64`) and the `"y"` list items get filled in with `12` because they -# retain their type (`int64`). Booleans get filled with True because `12.3` -# is not zero. Missing values remain in the same positions as in the original -# `array`. (To fill them in, use #ak.fill_none.) - -# See also #ak.zeros_like and #ak.ones_like. - -# (There is no equivalent of NumPy's `np.empty_like` because Awkward Arrays -# are immutable.) -# """ -# if dtype is not None: -# # In the case of strings and byte strings, -# # converting the fill avoids a ValueError. -# fill_value = dtype(fill_value) -# # Also, if the fill_value cannot be converted to the dtype -# # this should throw a clear, early, error. -# if dtype is bool: -# # then for bools, only 0 and 1 give correct string behavior -# fill_value = int(fill_value) - -# layout = ak._v2.operations.convert.to_layout( -# array, allow_record=True, allow_other=False -# ) - -# def getfunction(layout): -# if layout.parameter("__array__") == "bytestring" and fill_value is _ZEROS: -# nplike = ak.nplike.of(layout) -# asbytes = nplike.frombuffer(b"", dtype=np.uint8) -# return lambda: ak._v2.contents.ListArray64( -# ak._v2.index.Index64(nplike.zeros(len(layout), dtype=np.int64)), -# ak._v2.index.Index64(nplike.zeros(len(layout), dtype=np.int64)), -# ak._v2.contents.NumpyArray(asbytes, parameters={"__array__": "byte"}), -# parameters={"__array__": "bytestring"}, -# ) - -# elif layout.parameter("__array__") == "bytestring": -# nplike = ak.nplike.of(layout) -# if isinstance(fill_value, bytes): -# asbytes = fill_value -# elif isinstance(fill_value, str) or ( -# ak._v2._util.py27 and isinstance(fill_value, ak._v2._util.unicode) -# ): -# asbytes = fill_value.encode("utf-8", "surrogateescape") -# else: -# asbytes = str(fill_value).encode("utf-8", "surrogateescape") -# asbytes = nplike.frombuffer(asbytes, dtype=np.uint8) - -# return lambda: ak._v2.contents.ListArray64( -# ak._v2.index.Index64(nplike.zeros(len(layout), dtype=np.int64)), -# ak._v2.index.Index64( -# nplike.full(len(layout), len(asbytes), dtype=np.int64) -# ), -# ak._v2.contents.NumpyArray(asbytes, parameters={"__array__": "byte"}), -# parameters={"__array__": "bytestring"}, -# ) - -# elif layout.parameter("__array__") == "string" and fill_value is _ZEROS: -# nplike = ak.nplike.of(layout) -# asbytes = nplike.frombuffer(b"", dtype=np.uint8) -# return lambda: ak._v2.contents.ListArray64( -# ak._v2.index.Index64(nplike.zeros(len(layout), dtype=np.int64)), -# ak._v2.index.Index64(nplike.zeros(len(layout), dtype=np.int64)), -# ak._v2.contents.NumpyArray(asbytes, parameters={"__array__": "char"}), -# parameters={"__array__": "string"}, -# ) - -# elif layout.parameter("__array__") == "string": -# nplike = ak.nplike.of(layout) -# asstr = str(fill_value).encode("utf-8", "surrogateescape") -# asbytes = nplike.frombuffer(asstr, dtype=np.uint8) -# return lambda: ak._v2.contents.ListArray64( -# ak._v2.index.Index64(nplike.zeros(len(layout), dtype=np.int64)), -# ak._v2.index.Index64( -# nplike.full(len(layout), len(asbytes), dtype=np.int64) -# ), -# ak._v2.contents.NumpyArray(asbytes, parameters={"__array__": "char"}), -# parameters={"__array__": "string"}, -# ) - -# elif isinstance(layout, ak._v2.contents.NumpyArray): -# nplike = ak.nplike.of(layout) -# original = nplike.asarray(layout) -# if fill_value == 0 or fill_value is _ZEROS: -# return lambda: ak._v2.contents.NumpyArray( -# nplike.zeros_like(original), -# layout.identities, -# layout.parameters, -# ) -# elif fill_value == 1: -# return lambda: ak._v2.contents.NumpyArray( -# nplike.ones_like(original), -# layout.identities, -# layout.parameters, -# ) -# else: -# return lambda: ak._v2.contents.NumpyArray( -# nplike.full_like(original, fill_value), -# layout.identities, -# layout.parameters, -# ) -# else: -# return None - -# out = ak._v2._util.recursively_apply(layout, getfunction, pass_depth=False) -# if dtype is not None: -# out = strings_astype(out, dtype) -# out = values_astype(out, dtype) -# return ak._v2._util.maybe_wrap_like(out, array, behavior, highlevel) + + """ + Args: + array: Array to use as a model for a replacement that contains only + `fill_value`. + fill_value: Value to fill new new array with. + highlevel (bool, default is True): If True, return an #ak.Array; + otherwise, return a low-level #ak.layout.Content subclass. + behavior (None or dict): Custom #ak.behavior for the output array, if + high-level. + dtype (None or NumPy dtype)): Overrides the data type of the result. + + This is the equivalent of NumPy's `np.full_like` for Awkward Arrays. + + Although it's possible to produce an array of `fill_value` with the structure + of an `array` using #ak.broadcast_arrays: + + >>> array = ak.Array([[1, 2, 3], [], [4, 5]]) + >>> ak.broadcast_arrays(array, 1) + [, + ] + >>> ak.broadcast_arrays(array, 1.0) + [, + ] + + Such a technique takes its type from the scalar (`1` or `1.0`), rather than + the array. This function gets all types from the array, which might not be + the same in all parts of the structure. + + Here is an extreme example: + + >>> array = ak.Array([ + ... [{"x": 0.0, "y": []}, + ... {"x": 1.1, "y": [1]}, + ... {"x": 2.2, "y": [1, 2]}], + ... [], + ... [{"x": 3.3, "y": [1, 2, None, 3]}, + ... False, + ... False, + ... True, + ... {"x": 4.4, "y": [1, 2, None, 3, 4]}]]) + >>> ak.to_list(ak.full_like(array, 12.3)) + [[{"x": 12.3, "y": []}, + {"x": 12.3, "y": [12]}, + {"x": 12.3, "y": [12, 12]}], + [], + [{"x": 12.3, "y": [12, 12, None, 12]}, + True, + True, + True, + {"x": 12.3, "y": [12, 12, None, 12, 12]}]] + + The `"x"` values get filled in with `12.3` because they retain their type + (`float64`) and the `"y"` list items get filled in with `12` because they + retain their type (`int64`). Booleans get filled with True because `12.3` + is not zero. Missing values remain in the same positions as in the original + `array`. (To fill them in, use #ak.fill_none.) + + See also #ak.zeros_like and #ak.ones_like. + + (There is no equivalent of NumPy's `np.empty_like` because Awkward Arrays + are immutable.) + """ + if dtype is not None: + # In the case of strings and byte strings, + # converting the fill avoids a ValueError. + dtype = np.dtype(dtype) + nplike = ak.nplike.of(array) + fill_value = nplike.array([fill_value], dtype=dtype)[0] + # Also, if the fill_value cannot be converted to the dtype + # this should throw a clear, early, error. + if dtype == np.dtype(np.bool_): + # then for bools, only 0 and 1 give correct string behavior + fill_value = fill_value.view(np.uint8) + + layout = ak._v2.operations.convert.to_layout( + array, allow_record=True, allow_other=False + ) + + def action(layout, **kwargs): + if layout.parameter("__array__") == "bytestring" and fill_value is _ZEROS: + nplike = ak.nplike.of(layout) + asbytes = nplike.frombuffer(b"", dtype=np.uint8) + return ak._v2.contents.ListArray( + ak._v2.index.Index64(nplike.zeros(len(layout), dtype=np.int64)), + ak._v2.index.Index64(nplike.zeros(len(layout), dtype=np.int64)), + ak._v2.contents.NumpyArray(asbytes, parameters={"__array__": "byte"}), + parameters={"__array__": "bytestring"}, + ) + + elif layout.parameter("__array__") == "bytestring": + nplike = ak.nplike.of(layout) + if isinstance(fill_value, bytes): + asbytes = fill_value + else: + asbytes = str(fill_value).encode("utf-8", "surrogateescape") + asbytes = nplike.frombuffer(asbytes, dtype=np.uint8) + + return ak._v2.contents.ListArray( + ak._v2.index.Index64(nplike.zeros(len(layout), dtype=np.int64)), + ak._v2.index.Index64( + nplike.full(len(layout), len(asbytes), dtype=np.int64) + ), + ak._v2.contents.NumpyArray(asbytes, parameters={"__array__": "byte"}), + parameters={"__array__": "bytestring"}, + ) + + elif layout.parameter("__array__") == "string" and fill_value is _ZEROS: + nplike = ak.nplike.of(layout) + asbytes = nplike.frombuffer(b"", dtype=np.uint8) + return ak._v2.contents.ListArray( + ak._v2.index.Index64(nplike.zeros(len(layout), dtype=np.int64)), + ak._v2.index.Index64(nplike.zeros(len(layout), dtype=np.int64)), + ak._v2.contents.NumpyArray(asbytes, parameters={"__array__": "char"}), + parameters={"__array__": "string"}, + ) + + elif layout.parameter("__array__") == "string": + nplike = ak.nplike.of(layout) + asstr = str(fill_value).encode("utf-8", "surrogateescape") + asbytes = nplike.frombuffer(asstr, dtype=np.uint8) + return ak._v2.contents.ListArray( + ak._v2.index.Index64(nplike.zeros(len(layout), dtype=np.int64)), + ak._v2.index.Index64( + nplike.full(len(layout), len(asbytes), dtype=np.int64) + ), + ak._v2.contents.NumpyArray(asbytes, parameters={"__array__": "char"}), + parameters={"__array__": "string"}, + ) + + elif isinstance(layout, ak._v2.contents.NumpyArray): + nplike = ak.nplike.of(layout) + original = nplike.asarray(layout) + + if fill_value == 0 or fill_value is _ZEROS: + return ak._v2.contents.NumpyArray( + nplike.zeros_like(original), + layout.identifier, + layout.parameters, + ) + elif fill_value == 1: + return ak._v2.contents.NumpyArray( + nplike.ones_like(original), + layout.identifier, + layout.parameters, + ) + else: + return ak._v2.contents.NumpyArray( + nplike.full_like(original, fill_value), + layout.identifier, + layout.parameters, + ) + else: + return None + + out = layout.recursively_apply(action) + if dtype is not None: + out = ak._v2.operations.structure.strings_astype(out, dtype) + out = ak._v2.operations.structure.values_astype(out, dtype) + return out + return ak._v2._util.wrap(out, behavior, highlevel) diff --git a/src/awkward/_v2/operations/structure/ak_ones_like.py b/src/awkward/_v2/operations/structure/ak_ones_like.py index 92d533326a..193d14c65f 100644 --- a/src/awkward/_v2/operations/structure/ak_ones_like.py +++ b/src/awkward/_v2/operations/structure/ak_ones_like.py @@ -8,23 +8,23 @@ # @ak._v2._connect.numpy.implements("ones_like") def ones_like(array, highlevel=True, behavior=None, dtype=None): - raise NotImplementedError - -# """ -# Args: -# array: Array to use as a model for a replacement that contains only `1`. -# highlevel (bool, default is True): If True, return an #ak.Array; -# otherwise, return a low-level #ak.layout.Content subclass. -# behavior (None or dict): Custom #ak.behavior for the output array, if -# high-level. -# dtype (None or type): Overrides the data type of the result. - -# This is the equivalent of NumPy's `np.ones_like` for Awkward Arrays. - -# See #ak.full_like for details, and see also #ak.zeros_like. - -# (There is no equivalent of NumPy's `np.empty_like` because Awkward Arrays -# are immutable.) -# """ -# return full_like(array, 1, highlevel=highlevel, behavior=behavior, dtype=dtype) + """ + Args: + array: Array to use as a model for a replacement that contains only `1`. + highlevel (bool, default is True): If True, return an #ak.Array; + otherwise, return a low-level #ak.layout.Content subclass. + behavior (None or dict): Custom #ak.behavior for the output array, if + high-level. + dtype (None or NumPy dtype): Overrides the data type of the result. + + This is the equivalent of NumPy's `np.ones_like` for Awkward Arrays. + + See #ak.full_like for details, and see also #ak.zeros_like. + + (There is no equivalent of NumPy's `np.empty_like` because Awkward Arrays + are immutable.) + """ + return ak._v2.operations.structure.full_like( + array, 1, highlevel=highlevel, behavior=behavior, dtype=dtype + ) diff --git a/src/awkward/_v2/operations/structure/ak_zeros_like.py b/src/awkward/_v2/operations/structure/ak_zeros_like.py index 950711c855..fcaa2511db 100644 --- a/src/awkward/_v2/operations/structure/ak_zeros_like.py +++ b/src/awkward/_v2/operations/structure/ak_zeros_like.py @@ -6,30 +6,32 @@ np = ak.nplike.NumpyMetadata.instance() -# @ak._v2._connect.numpy.implements("zeros_like") -def zeros_like(array, highlevel=True, behavior=None, dtype=None): - raise NotImplementedError - - -# """ -# Args: -# array: Array to use as a model for a replacement that contains only `0`. -# highlevel (bool, default is True): If True, return an #ak.Array; -# otherwise, return a low-level #ak.layout.Content subclass. -# behavior (None or dict): Custom #ak.behavior for the output array, if -# high-level. -# dtype (None or type): Overrides the data type of the result. - -# This is the equivalent of NumPy's `np.zeros_like` for Awkward Arrays. - -# See #ak.full_like for details, and see also #ak.ones_like. +_ZEROS = object() -# (There is no equivalent of NumPy's `np.empty_like` because Awkward Arrays -# are immutable.) -# """ -# if dtype is not None: -# return full_like(array, 0, highlevel=highlevel, behavior=behavior, dtype=dtype) -# return full_like(array, _ZEROS, highlevel=highlevel, behavior=behavior, dtype=dtype) +# @ak._v2._connect.numpy.implements("zeros_like") +def zeros_like(array, highlevel=True, behavior=None, dtype=None): -_ZEROS = object() + """ + Args: + array: Array to use as a model for a replacement that contains only `0`. + highlevel (bool, default is True): If True, return an #ak.Array; + otherwise, return a low-level #ak.layout.Content subclass. + behavior (None or dict): Custom #ak.behavior for the output array, if + high-level. + dtype (None or NumPy dtype)): Overrides the data type of the result. + + This is the equivalent of NumPy's `np.zeros_like` for Awkward Arrays. + + See #ak.full_like for details, and see also #ak.ones_like. + + (There is no equivalent of NumPy's `np.empty_like` because Awkward Arrays + are immutable.) + """ + if dtype is not None: + return ak._v2.operations.structure.full_like( + array, 0, highlevel=highlevel, behavior=behavior, dtype=dtype + ) + return ak._v2.operations.structure.full_like( + array, _ZEROS, highlevel=highlevel, behavior=behavior, dtype=dtype + ) diff --git a/tests/v2/test_0493-zeros-ones-full-like.py b/tests/v2/test_0493-zeros-ones-full-like.py new file mode 100644 index 0000000000..41808f3b1e --- /dev/null +++ b/tests/v2/test_0493-zeros-ones-full-like.py @@ -0,0 +1,159 @@ +# BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE + +import datetime +import pytest # noqa: F401 +import numpy as np # noqa: F401 +import awkward as ak # noqa: F401 + + +def test(): + array = ak._v2.Array( + [ + [{"x": 0.0, "y": []}, {"x": 1.1, "y": [1]}, {"x": 2.2, "y": [1, 2]}], + [], + [ + {"x": 3.3, "y": [1, 2, None, 3]}, + False, + False, + True, + {"x": 4.4, "y": [1, 2, None, 3, 4]}, + ], + ] + ) + + assert ak._v2.operations.structure.full_like(array, 12.3).tolist() == [ + [{"x": 12.3, "y": []}, {"x": 12.3, "y": [12]}, {"x": 12.3, "y": [12, 12]}], + [], + [ + {"x": 12.3, "y": [12, 12, None, 12]}, + True, + True, + True, + {"x": 12.3, "y": [12, 12, None, 12, 12]}, + ], + ] + + assert ak._v2.operations.structure.zeros_like(array).tolist() == [ + [{"x": 0.0, "y": []}, {"x": 0.0, "y": [0]}, {"x": 0.0, "y": [0, 0]}], + [], + [ + {"x": 0.0, "y": [0, 0, None, 0]}, + False, + False, + False, + {"x": 0.0, "y": [0, 0, None, 0, 0]}, + ], + ] + + assert ak._v2.operations.structure.ones_like(array).tolist() == [ + [{"x": 1.0, "y": []}, {"x": 1.0, "y": [1]}, {"x": 1.0, "y": [1, 1]}], + [], + [ + {"x": 1.0, "y": [1, 1, None, 1]}, + True, + True, + True, + {"x": 1.0, "y": [1, 1, None, 1, 1]}, + ], + ] + + array = ak._v2.Array([["one", "two", "three"], [], ["four", "five"]]) + assert ak._v2.operations.structure.full_like(array, "hello").tolist() == [ + ["hello", "hello", "hello"], + [], + ["hello", "hello"], + ] + assert ak._v2.operations.structure.full_like(array, 1).tolist() == [ + ["1", "1", "1"], + [], + ["1", "1"], + ] + assert ak._v2.operations.structure.full_like(array, 0).tolist() == [ + ["0", "0", "0"], + [], + ["0", "0"], + ] + assert ak._v2.operations.structure.ones_like(array).tolist() == [ + ["1", "1", "1"], + [], + ["1", "1"], + ] + assert ak._v2.operations.structure.zeros_like(array).tolist() == [ + ["", "", ""], + [], + ["", ""], + ] + + array = ak._v2.Array([[b"one", b"two", b"three"], [], [b"four", b"five"]]) + assert ak._v2.operations.structure.full_like(array, b"hello").tolist() == [ + [b"hello", b"hello", b"hello"], + [], + [b"hello", b"hello"], + ] + assert ak._v2.operations.structure.full_like(array, 1).tolist() == [ + [b"1", b"1", b"1"], + [], + [b"1", b"1"], + ] + assert ak._v2.operations.structure.full_like(array, 0).tolist() == [ + [b"0", b"0", b"0"], + [], + [b"0", b"0"], + ] + assert ak._v2.operations.structure.ones_like(array).tolist() == [ + [b"1", b"1", b"1"], + [], + [b"1", b"1"], + ] + assert ak._v2.operations.structure.zeros_like(array).tolist() == [ + [b"", b"", b""], + [], + [b"", b""], + ] + + +@pytest.mark.skip(reason="Tests passing, will be enabled in the strings_astype PR.") +def test_full_like_types(): + + array = ak._v2.highlevel.Array( + np.array(["2020-07-27T10:41:11", "2019-01-01", "2020-01-01"], "datetime64[s]") + ) + + assert ak._v2.operations.structure.full_like( + array, "2020-07-27T10:41:11" + ).tolist() == [ + datetime.datetime(2020, 7, 27, 10, 41, 11), + datetime.datetime(2020, 7, 27, 10, 41, 11), + datetime.datetime(2020, 7, 27, 10, 41, 11), + ] + + array = np.array( + ["2020-07-27T10:41:11", "2019-01-01", "2020-01-01"], "datetime64[25s]" + ) + + assert ak._v2.operations.structure.full_like( + array, "2021-06-03T10:00" + ).tolist() == [ + datetime.datetime(2021, 6, 3, 10, 0), + datetime.datetime(2021, 6, 3, 10, 0), + datetime.datetime(2021, 6, 3, 10, 0), + ] + + array = ak._v2.contents.NumpyArray(np.array([0, 2, 2, 3], dtype="i4")) + + assert ( + str(ak._v2.operations.structure.full_like(array, 11, dtype="i8").type) + == "4 * int64" + ) + assert ( + str( + ak._v2.operations.structure.full_like( + array, 11, dtype=np.dtype(np.int64) + ).type + ) + == "4 * int64" + ) + assert ( + str(ak._v2.operations.structure.full_like(array, 11, dtype=np.int64).type) + == "4 * int64" + ) diff --git a/tests/v2/test_0813-full-like-dtype-arg.py b/tests/v2/test_0813-full-like-dtype-arg.py new file mode 100644 index 0000000000..fda1237aa3 --- /dev/null +++ b/tests/v2/test_0813-full-like-dtype-arg.py @@ -0,0 +1,122 @@ +# BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE + + +import pytest # noqa: F401 +import numpy as np # noqa: F401 +import awkward as ak # noqa: F401 + + +@pytest.mark.skip(reason="FIXME: ak.strings_astype not implemented") +def test(): + array = ak._v2.Array( + [ + [{"x": 0.0, "y": []}, {"x": 1.1, "y": [1]}, {"x": 2.2, "y": [1, 2]}], + [], + [ + {"x": 3.3, "y": [1, 2, None, 3]}, + False, + False, + True, + {"x": 4.4, "y": [1, 2, None, 3, 4]}, + ], + ] + ) + + def assert_array_type(new_array, intended_type): + """helper function to check each part of the array took the intended type""" + assert isinstance(new_array[0][0]["x"], intended_type) + assert isinstance(new_array[0][1]["x"], intended_type) + assert isinstance(new_array[0][1]["y"][0], intended_type) + assert isinstance(new_array[0][2]["x"], intended_type) + assert isinstance(new_array[0][2]["y"][0], intended_type) + assert isinstance(new_array[0][2]["y"][1], intended_type) + assert isinstance(new_array[2][0]["x"], intended_type) + assert isinstance(new_array[2][0]["y"][0], intended_type) + assert isinstance(new_array[2][0]["y"][1], intended_type) + assert isinstance(new_array[2][0]["y"][3], intended_type) + assert isinstance(new_array[2][1], intended_type) + assert isinstance(new_array[2][2], intended_type) + assert isinstance(new_array[2][3], intended_type) + assert isinstance(new_array[2][4]["x"], intended_type) + assert isinstance(new_array[2][4]["y"][0], intended_type) + assert isinstance(new_array[2][4]["y"][1], intended_type) + assert isinstance(new_array[2][4]["y"][3], intended_type) + assert isinstance(new_array[2][4]["y"][4], intended_type) + + int_type = ak._v2.operations.structure.full_like(array, 12, dtype=int) + float_type = ak._v2.operations.structure.full_like(array, 12, dtype=float) + assert int_type.tolist() == float_type.tolist() + assert_array_type(int_type, int) + assert_array_type(float_type, float) + + bool_type = ak._v2.operations.structure.full_like(array, 12, dtype=bool) + assert_array_type(bool_type, bool) + + int_type = ak._v2.operations.structure.full_like(array, -1.2, dtype=int) + float_type = ak._v2.operations.structure.full_like(array, -1.2, dtype=float) + bool_type = ak._v2.operations.structure.full_like(array, -1.2, dtype=bool) + assert_array_type(int_type, int) + assert_array_type(float_type, float) + assert_array_type(bool_type, bool) + + int_type = ak._v2.operations.structure.zeros_like(array, dtype=int) + float_type = ak._v2.operations.structure.zeros_like(array, dtype=float) + bool_type = ak._v2.operations.structure.zeros_like(array, dtype=bool) + assert int_type.tolist() == float_type.tolist() + assert int_type.tolist() == bool_type.tolist() + assert_array_type(int_type, int) + assert_array_type(float_type, float) + assert_array_type(bool_type, bool) + + int_type = ak._v2.operations.structure.ones_like(array, dtype=int) + float_type = ak._v2.operations.structure.ones_like(array, dtype=float) + bool_type = ak._v2.operations.structure.ones_like(array, dtype=bool) + assert int_type.tolist() == float_type.tolist() + assert int_type.tolist() == bool_type.tolist() + assert_array_type(int_type, int) + assert_array_type(float_type, float) + assert_array_type(bool_type, bool) + + array = ak.Array([["one", "two", "three"], [], ["four", "five"]]) + + def assert_array_type(new_array, intended_type): + """helper function to check each part of the array took the intended type""" + assert isinstance(new_array[0][0], intended_type) + assert isinstance(new_array[0][1], intended_type) + assert isinstance(new_array[0][2], intended_type) + assert isinstance(new_array[2][0], intended_type) + assert isinstance(new_array[2][1], intended_type) + + int_type = ak._v2.operations.structure.full_like(array, 12, dtype=int) + float_type = ak._v2.operations.structure.full_like(array, 12, dtype=float) + assert int_type.tolist() == float_type.tolist() + assert_array_type(int_type, int) + assert_array_type(float_type, float) + + bool_type = ak._v2.operations.structure.full_like(array, 12, dtype=bool) + assert_array_type(bool_type, bool) + + int_type = ak._v2.operations.structure.full_like(array, -1.2, dtype=int) + float_type = ak._v2.operations.structure.full_like(array, -1.2, dtype=float) + bool_type = ak._v2.operations.structure.full_like(array, -1.2, dtype=bool) + assert_array_type(int_type, int) + assert_array_type(float_type, float) + assert_array_type(bool_type, bool) + + int_type = ak._v2.operations.structure.zeros_like(array, dtype=int) + float_type = ak._v2.operations.structure.zeros_like(array, dtype=float) + bool_type = ak._v2.operations.structure.zeros_like(array, dtype=bool) + assert int_type.tolist() == float_type.tolist() + assert int_type.tolist() == bool_type.tolist() + assert_array_type(int_type, int) + assert_array_type(float_type, float) + assert_array_type(bool_type, bool) + + int_type = ak._v2.operations.structure.ones_like(array, dtype=int) + float_type = ak._v2.operations.structure.ones_like(array, dtype=float) + bool_type = ak._v2.operations.structure.ones_like(array, dtype=bool) + assert int_type.tolist() == float_type.tolist() + assert int_type.tolist() == bool_type.tolist() + assert_array_type(int_type, int) + assert_array_type(float_type, float) + assert_array_type(bool_type, bool) diff --git a/tests/v2/test_0835-datetime-type.py b/tests/v2/test_0835-datetime-type.py index eaf105917a..19a7ef26d3 100644 --- a/tests/v2/test_0835-datetime-type.py +++ b/tests/v2/test_0835-datetime-type.py @@ -294,7 +294,6 @@ def test_all_nonzero(): ] -@pytest.mark.skip(reason="FIXME: needs ak._v2.operations.structure.fill_none") def test_argmin_argmax_axis_None(): array = ak._v2.highlevel.Array( [