dask-array 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (144) hide show
  1. dask_array/__init__.py +228 -0
  2. dask_array/_backends.py +76 -0
  3. dask_array/_backends_array.py +99 -0
  4. dask_array/_blockwise.py +1410 -0
  5. dask_array/_broadcast.py +272 -0
  6. dask_array/_chunk.py +445 -0
  7. dask_array/_chunk_types.py +54 -0
  8. dask_array/_collection.py +1644 -0
  9. dask_array/_concatenate.py +331 -0
  10. dask_array/_core_utils.py +1365 -0
  11. dask_array/_dispatch.py +141 -0
  12. dask_array/_einsum.py +277 -0
  13. dask_array/_expr.py +544 -0
  14. dask_array/_expr_flow.py +586 -0
  15. dask_array/_gufunc.py +805 -0
  16. dask_array/_histogram.py +617 -0
  17. dask_array/_map_blocks.py +652 -0
  18. dask_array/_new_collection.py +10 -0
  19. dask_array/_numpy_compat.py +135 -0
  20. dask_array/_overlap.py +1159 -0
  21. dask_array/_rechunk.py +1050 -0
  22. dask_array/_reshape.py +710 -0
  23. dask_array/_routines.py +102 -0
  24. dask_array/_shuffle.py +448 -0
  25. dask_array/_stack.py +264 -0
  26. dask_array/_svg.py +291 -0
  27. dask_array/_templates.py +29 -0
  28. dask_array/_test_utils.py +257 -0
  29. dask_array/_ufunc.py +385 -0
  30. dask_array/_utils.py +349 -0
  31. dask_array/_visualize.py +223 -0
  32. dask_array/_xarray.py +337 -0
  33. dask_array/core/__init__.py +34 -0
  34. dask_array/core/_blockwise_funcs.py +312 -0
  35. dask_array/core/_conversion.py +422 -0
  36. dask_array/core/_from_graph.py +97 -0
  37. dask_array/creation/__init__.py +71 -0
  38. dask_array/creation/_arange.py +121 -0
  39. dask_array/creation/_diag.py +116 -0
  40. dask_array/creation/_diagonal.py +241 -0
  41. dask_array/creation/_eye.py +103 -0
  42. dask_array/creation/_linspace.py +102 -0
  43. dask_array/creation/_mesh.py +134 -0
  44. dask_array/creation/_ones_zeros.py +454 -0
  45. dask_array/creation/_pad.py +270 -0
  46. dask_array/creation/_repeat.py +55 -0
  47. dask_array/creation/_tile.py +36 -0
  48. dask_array/creation/_tri.py +28 -0
  49. dask_array/creation/_utils.py +296 -0
  50. dask_array/fft.py +320 -0
  51. dask_array/io/__init__.py +39 -0
  52. dask_array/io/_base.py +10 -0
  53. dask_array/io/_from_array.py +257 -0
  54. dask_array/io/_from_delayed.py +95 -0
  55. dask_array/io/_from_graph.py +54 -0
  56. dask_array/io/_from_npy_stack.py +67 -0
  57. dask_array/io/_store.py +336 -0
  58. dask_array/io/_tiledb.py +159 -0
  59. dask_array/io/_to_npy_stack.py +65 -0
  60. dask_array/io/_zarr.py +449 -0
  61. dask_array/linalg/__init__.py +39 -0
  62. dask_array/linalg/_cholesky.py +234 -0
  63. dask_array/linalg/_lu.py +300 -0
  64. dask_array/linalg/_norm.py +94 -0
  65. dask_array/linalg/_qr.py +601 -0
  66. dask_array/linalg/_solve.py +349 -0
  67. dask_array/linalg/_svd.py +394 -0
  68. dask_array/linalg/_tensordot.py +334 -0
  69. dask_array/linalg/_utils.py +74 -0
  70. dask_array/manipulation/__init__.py +45 -0
  71. dask_array/manipulation/_expand.py +321 -0
  72. dask_array/manipulation/_flip.py +92 -0
  73. dask_array/manipulation/_roll.py +78 -0
  74. dask_array/manipulation/_transpose.py +309 -0
  75. dask_array/random/__init__.py +125 -0
  76. dask_array/random/_choice.py +181 -0
  77. dask_array/random/_expr.py +256 -0
  78. dask_array/random/_generator.py +441 -0
  79. dask_array/random/_random_state.py +259 -0
  80. dask_array/random/_utils.py +84 -0
  81. dask_array/reductions/__init__.py +84 -0
  82. dask_array/reductions/_arg_reduction.py +130 -0
  83. dask_array/reductions/_common.py +1082 -0
  84. dask_array/reductions/_cumulative.py +522 -0
  85. dask_array/reductions/_percentile.py +261 -0
  86. dask_array/reductions/_reduction.py +725 -0
  87. dask_array/reductions/_trace.py +56 -0
  88. dask_array/routines/__init__.py +133 -0
  89. dask_array/routines/_apply.py +84 -0
  90. dask_array/routines/_bincount.py +112 -0
  91. dask_array/routines/_broadcast.py +111 -0
  92. dask_array/routines/_coarsen.py +115 -0
  93. dask_array/routines/_diff.py +79 -0
  94. dask_array/routines/_gradient.py +158 -0
  95. dask_array/routines/_indexing.py +65 -0
  96. dask_array/routines/_insert_delete.py +132 -0
  97. dask_array/routines/_misc.py +122 -0
  98. dask_array/routines/_nonzero.py +72 -0
  99. dask_array/routines/_search.py +123 -0
  100. dask_array/routines/_select.py +113 -0
  101. dask_array/routines/_statistics.py +171 -0
  102. dask_array/routines/_topk.py +82 -0
  103. dask_array/routines/_triangular.py +74 -0
  104. dask_array/routines/_unique.py +232 -0
  105. dask_array/routines/_where.py +62 -0
  106. dask_array/slicing/__init__.py +67 -0
  107. dask_array/slicing/_basic.py +550 -0
  108. dask_array/slicing/_blocks.py +138 -0
  109. dask_array/slicing/_bool_index.py +145 -0
  110. dask_array/slicing/_setitem.py +329 -0
  111. dask_array/slicing/_squeeze.py +101 -0
  112. dask_array/slicing/_utils.py +1133 -0
  113. dask_array/slicing/_vindex.py +282 -0
  114. dask_array/stacking/__init__.py +15 -0
  115. dask_array/stacking/_block.py +83 -0
  116. dask_array/stacking/_simple.py +58 -0
  117. dask_array/templates/array.html.j2 +48 -0
  118. dask_array/tests/__init__.py +0 -0
  119. dask_array/tests/conftest.py +22 -0
  120. dask_array/tests/test_api.py +40 -0
  121. dask_array/tests/test_binary_op_chunks.py +107 -0
  122. dask_array/tests/test_coarse_slice_through_blockwise.py +362 -0
  123. dask_array/tests/test_collection.py +799 -0
  124. dask_array/tests/test_creation.py +1102 -0
  125. dask_array/tests/test_expr_flow.py +143 -0
  126. dask_array/tests/test_linalg.py +1130 -0
  127. dask_array/tests/test_map_blocks_multi_output.py +104 -0
  128. dask_array/tests/test_rechunk_pushdown.py +214 -0
  129. dask_array/tests/test_reductions.py +1091 -0
  130. dask_array/tests/test_routines.py +2853 -0
  131. dask_array/tests/test_shuffle_chunks.py +67 -0
  132. dask_array/tests/test_slice_pushdown.py +968 -0
  133. dask_array/tests/test_slice_through_blockwise.py +678 -0
  134. dask_array/tests/test_slice_through_overlap.py +366 -0
  135. dask_array/tests/test_slice_through_reshape.py +272 -0
  136. dask_array/tests/test_slicing.py +839 -0
  137. dask_array/tests/test_transpose_slice_pushdown.py +208 -0
  138. dask_array/tests/test_visualize.py +94 -0
  139. dask_array/tests/test_xarray.py +193 -0
  140. dask_array-0.1.0.dist-info/METADATA +48 -0
  141. dask_array-0.1.0.dist-info/RECORD +144 -0
  142. dask_array-0.1.0.dist-info/WHEEL +4 -0
  143. dask_array-0.1.0.dist-info/entry_points.txt +2 -0
  144. dask_array-0.1.0.dist-info/licenses/LICENSE +29 -0
@@ -0,0 +1,134 @@
1
+ from __future__ import annotations
2
+
3
+ import itertools
4
+
5
+ import numpy as np
6
+
7
+ from dask_array._collection import asarray
8
+ from dask.utils import derived_from
9
+
10
+
11
+ @derived_from(np)
12
+ def meshgrid(*xi, sparse=False, indexing="xy", **kwargs):
13
+ from dask_array._routines import broadcast_arrays
14
+ from dask_array._numpy_compat import NUMPY_GE_200
15
+
16
+ sparse = bool(sparse)
17
+
18
+ if "copy" in kwargs:
19
+ raise NotImplementedError("`copy` not supported")
20
+
21
+ if kwargs:
22
+ raise TypeError("unsupported keyword argument(s) provided")
23
+
24
+ if indexing not in ("ij", "xy"):
25
+ raise ValueError("`indexing` must be `'ij'` or `'xy'`")
26
+
27
+ xi = [asarray(e) for e in xi]
28
+ xi = [e.flatten() for e in xi]
29
+
30
+ if indexing == "xy" and len(xi) > 1:
31
+ xi[0], xi[1] = xi[1], xi[0]
32
+
33
+ grid = []
34
+ for i in range(len(xi)):
35
+ s = len(xi) * [None]
36
+ s[i] = slice(None)
37
+ s = tuple(s)
38
+
39
+ r = xi[i][s]
40
+
41
+ grid.append(r)
42
+
43
+ if not sparse:
44
+ grid = broadcast_arrays(*grid)
45
+
46
+ if indexing == "xy" and len(xi) > 1:
47
+ grid = (grid[1], grid[0], *grid[2:])
48
+
49
+ out_type = tuple if NUMPY_GE_200 else list
50
+ return out_type(grid)
51
+
52
+
53
+ def indices(dimensions, dtype=int, chunks="auto"):
54
+ """
55
+ Implements NumPy's ``indices`` for Dask Arrays.
56
+
57
+ Generates a grid of indices covering the dimensions provided.
58
+
59
+ The final array has the shape ``(len(dimensions), *dimensions)``. The
60
+ chunks are used to specify the chunking for axis 1 up to
61
+ ``len(dimensions)``. The 0th axis always has chunks of length 1.
62
+
63
+ Parameters
64
+ ----------
65
+ dimensions : sequence of ints
66
+ The shape of the index grid.
67
+ dtype : dtype, optional
68
+ Type to use for the array. Default is ``int``.
69
+ chunks : sequence of ints, str
70
+ The size of each block. Must be one of the following forms:
71
+
72
+ - A blocksize like (500, 1000)
73
+ - A size in bytes, like "100 MiB" which will choose a uniform
74
+ block-like shape
75
+ - The word "auto" which acts like the above, but uses a configuration
76
+ value ``array.chunk-size`` for the chunk size
77
+
78
+ Note that the last block will have fewer samples if ``len(array) % chunks != 0``.
79
+
80
+ Returns
81
+ -------
82
+ grid : dask array
83
+ """
84
+ import numpy as np
85
+
86
+ from dask_array._collection import stack
87
+ from dask_array._core_utils import normalize_chunks
88
+
89
+ from ._arange import arange
90
+ from ._ones_zeros import empty
91
+
92
+ dimensions = tuple(dimensions)
93
+ dtype = np.dtype(dtype)
94
+ chunks = normalize_chunks(chunks, shape=dimensions, dtype=dtype)
95
+
96
+ if len(dimensions) != len(chunks):
97
+ raise ValueError("Need same number of chunks as dimensions.")
98
+
99
+ xi = []
100
+ for i in range(len(dimensions)):
101
+ xi.append(arange(dimensions[i], dtype=dtype, chunks=(chunks[i],)))
102
+
103
+ grid = []
104
+ if all(dimensions):
105
+ grid = meshgrid(*xi, indexing="ij")
106
+
107
+ if grid:
108
+ grid = stack(grid)
109
+ else:
110
+ grid = empty((len(dimensions),) + dimensions, dtype=dtype, chunks=(1,) + chunks)
111
+
112
+ return grid
113
+
114
+
115
+ @derived_from(np)
116
+ def fromfunction(func, chunks="auto", shape=None, dtype=None, **kwargs):
117
+ from dask_array._collection import blockwise
118
+ from dask_array._core_utils import normalize_chunks
119
+
120
+ from ._arange import arange
121
+
122
+ dtype = dtype or float
123
+ chunks = normalize_chunks(chunks, shape, dtype=dtype)
124
+
125
+ inds = tuple(range(len(shape)))
126
+
127
+ arrs = [arange(s, dtype=dtype, chunks=c) for s, c in zip(shape, chunks)]
128
+ arrs = meshgrid(*arrs, indexing="ij")
129
+
130
+ args = sum(zip(arrs, itertools.repeat(inds)), ())
131
+
132
+ res = blockwise(func, inds, *args, token="fromfunction", **kwargs)
133
+
134
+ return res
@@ -0,0 +1,454 @@
1
+ from __future__ import annotations
2
+
3
+ import functools
4
+ from functools import partial
5
+
6
+ import numpy as np
7
+
8
+ from dask_array._new_collection import new_collection
9
+ from dask._task_spec import Task
10
+ from dask_array._collection import asarray
11
+ from dask_array._expr import ArrayExpr
12
+ from dask_array._utils import meta_from_array
13
+
14
+ from ._utils import _get_like_function_shapes_chunks, _parse_wrap_args, broadcast_trick
15
+
16
+
17
+ class BroadcastTrick(ArrayExpr):
18
+ _parameters = ["shape", "dtype", "chunks", "meta", "kwargs", "name"]
19
+ _defaults = {"meta": None, "name": None}
20
+ _is_blockwise_fusable = True
21
+
22
+ @functools.cached_property
23
+ def _name(self):
24
+ custom_name = self.operand("name")
25
+ if custom_name is not None:
26
+ return custom_name
27
+ return f"{self._funcname}-{self.deterministic_token}"
28
+
29
+ @functools.cached_property
30
+ def _meta(self):
31
+ return meta_from_array(self.operand("meta"), ndim=self.ndim, dtype=self.operand("dtype"))
32
+
33
+ @functools.cached_property
34
+ def _wrapped_func(self):
35
+ """Cache the wrapped broadcast function."""
36
+ func = broadcast_trick(self.func)
37
+ k = self.kwargs.copy()
38
+ k.pop("meta", None)
39
+ return partial(func, meta=self._meta, dtype=self.dtype, **k)
40
+
41
+ def _layer(self) -> dict:
42
+ from itertools import product
43
+
44
+ result = {}
45
+ for block_id in product(*[range(len(c)) for c in self.chunks]):
46
+ key = (self._name, *block_id)
47
+ result[key] = self._task(key, block_id)
48
+ return result
49
+
50
+ def _task(self, key, block_id: tuple[int, ...]) -> Task:
51
+ """Generate task for a specific output block."""
52
+ # Compute chunk shape for this block
53
+ chunk_shape = tuple(self.chunks[i][block_id[i]] for i in range(len(block_id)))
54
+ return Task(key, self._wrapped_func, chunk_shape)
55
+
56
+ def _input_block_id(self, dep, block_id: tuple[int, ...]) -> tuple[int, ...]:
57
+ """BroadcastTrick has no dependencies, so this is never called."""
58
+ return block_id
59
+
60
+ def _simplify_up(self, parent, dependents):
61
+ """Allow slice and shuffle operations to simplify BroadcastTrick."""
62
+ from dask_array._shuffle import Shuffle
63
+ from dask_array.slicing import SliceSlicesIntegers
64
+
65
+ if isinstance(parent, SliceSlicesIntegers):
66
+ return self._accept_slice(parent)
67
+ if isinstance(parent, Shuffle):
68
+ return self._accept_shuffle(parent)
69
+ return None
70
+
71
+ def _accept_shuffle(self, shuffle_expr):
72
+ """Accept a shuffle - create new BroadcastTrick with shuffled shape.
73
+
74
+ Since all values are identical, we don't need to actually shuffle,
75
+ just create a new constant array with the correct output shape.
76
+ """
77
+ axis = shuffle_expr.axis
78
+ indexer = shuffle_expr.indexer
79
+
80
+ # Compute new shape - output size is total indices in indexer
81
+ new_size = sum(len(chunk) for chunk in indexer)
82
+ new_shape = list(self.shape)
83
+ new_shape[axis] = new_size
84
+
85
+ # Compute new chunks - one chunk per indexer group
86
+ new_axis_chunks = tuple(len(chunk) for chunk in indexer)
87
+ new_chunks = list(self.chunks)
88
+ new_chunks[axis] = new_axis_chunks
89
+
90
+ return self.substitute_parameters(
91
+ {
92
+ "shape": tuple(new_shape),
93
+ "chunks": tuple(new_chunks),
94
+ "name": None,
95
+ }
96
+ )
97
+
98
+ def _accept_slice(self, slice_expr):
99
+ """Accept a slice by creating a smaller BroadcastTrick.
100
+
101
+ For ones, zeros, full, empty - just create a new instance with
102
+ the sliced shape and chunks.
103
+ """
104
+ from numbers import Integral
105
+
106
+ index = slice_expr.index
107
+ old_shape = self.shape
108
+ old_chunks = self.chunks
109
+
110
+ # Pad index to full length
111
+ full_index = index + (slice(None),) * (len(old_shape) - len(index))
112
+
113
+ # Handle integers and newaxis - for now, only handle simple slices
114
+ if any(idx is None for idx in full_index):
115
+ return None
116
+ if any(isinstance(idx, Integral) for idx in full_index):
117
+ return None
118
+
119
+ # Compute new shape and chunks from slices
120
+ new_shape = []
121
+ new_chunks = []
122
+ for i, idx in enumerate(full_index):
123
+ if isinstance(idx, slice):
124
+ # Normalize slice
125
+ start, stop, step = idx.indices(old_shape[i])
126
+ if step != 1:
127
+ return None # Don't handle non-unit steps
128
+ new_dim = max(0, stop - start)
129
+ new_shape.append(new_dim)
130
+
131
+ # Compute new chunks for this dimension
132
+ old_axis_chunks = old_chunks[i]
133
+ axis_chunks = []
134
+ cumsum = 0
135
+ for chunk_size in old_axis_chunks:
136
+ chunk_start = cumsum
137
+ chunk_end = cumsum + chunk_size
138
+ cumsum = chunk_end
139
+
140
+ # Intersection of [chunk_start, chunk_end) with [start, stop)
141
+ overlap_start = max(chunk_start, start)
142
+ overlap_end = min(chunk_end, stop)
143
+ if overlap_end > overlap_start:
144
+ axis_chunks.append(overlap_end - overlap_start)
145
+
146
+ new_chunks.append(tuple(axis_chunks) if axis_chunks else (0,))
147
+ else:
148
+ return None # Unexpected index type
149
+
150
+ # Substitute shape and chunks, clear name for new expression
151
+ return self.substitute_parameters(
152
+ {
153
+ "shape": tuple(new_shape),
154
+ "chunks": tuple(new_chunks),
155
+ "name": None,
156
+ }
157
+ )
158
+
159
+
160
+ class Ones(BroadcastTrick):
161
+ func = staticmethod(np.ones_like)
162
+
163
+
164
+ class Zeros(BroadcastTrick):
165
+ func = staticmethod(np.zeros_like)
166
+
167
+
168
+ class Empty(BroadcastTrick):
169
+ func = staticmethod(np.empty_like)
170
+
171
+
172
+ class Full(BroadcastTrick):
173
+ func = staticmethod(np.full_like)
174
+
175
+
176
+ def wrap_func_shape_as_first_arg(*args, klass, **kwargs):
177
+ """
178
+ Transform np creation function into blocked version
179
+ """
180
+ if "shape" not in kwargs:
181
+ shape, args = args[0], args[1:]
182
+ else:
183
+ shape = kwargs.pop("shape")
184
+
185
+ if isinstance(shape, ArrayExpr):
186
+ raise TypeError("Dask array input not supported. Please use tuple, list, or a 1D numpy array instead.")
187
+
188
+ name = kwargs.pop("name", None)
189
+ parsed = _parse_wrap_args(klass.func, args, kwargs, shape)
190
+ return new_collection(
191
+ klass(
192
+ parsed["shape"],
193
+ parsed["dtype"],
194
+ parsed["chunks"],
195
+ kwargs.get("meta"),
196
+ kwargs,
197
+ name,
198
+ )
199
+ )
200
+
201
+
202
+ def wrap(func, **kwargs):
203
+ return partial(func, **kwargs)
204
+
205
+
206
+ ones = wrap(wrap_func_shape_as_first_arg, klass=Ones, dtype="f8")
207
+ zeros = wrap(wrap_func_shape_as_first_arg, klass=Zeros, dtype="f8")
208
+ empty = wrap(wrap_func_shape_as_first_arg, klass=Empty, dtype="f8")
209
+ _full = wrap(wrap_func_shape_as_first_arg, klass=Full, dtype="f8")
210
+
211
+
212
+ def empty_like(a, dtype=None, order="C", chunks=None, name=None, shape=None):
213
+ """
214
+ Return a new array with the same shape and type as a given array.
215
+
216
+ Parameters
217
+ ----------
218
+ a : array_like
219
+ The shape and data-type of `a` define these same attributes of the
220
+ returned array.
221
+ dtype : data-type, optional
222
+ Overrides the data type of the result.
223
+ order : {'C', 'F'}, optional
224
+ Whether to store multidimensional data in C- or Fortran-contiguous
225
+ (row- or column-wise) order in memory.
226
+ chunks : sequence of ints
227
+ The number of samples on each block. Note that the last block will have
228
+ fewer samples if ``len(array) % chunks != 0``.
229
+ name : str, optional
230
+ An optional keyname for the array. Defaults to hashing the input
231
+ keyword arguments.
232
+ shape : int or sequence of ints, optional.
233
+ Overrides the shape of the result.
234
+
235
+ Returns
236
+ -------
237
+ out : ndarray
238
+ Array of uninitialized (arbitrary) data with the same
239
+ shape and type as `a`.
240
+
241
+ See Also
242
+ --------
243
+ ones_like : Return an array of ones with shape and type of input.
244
+ zeros_like : Return an array of zeros with shape and type of input.
245
+ empty : Return a new uninitialized array.
246
+ ones : Return a new array setting values to one.
247
+ zeros : Return a new array setting values to zero.
248
+
249
+ Notes
250
+ -----
251
+ This function does *not* initialize the returned array; to do that use
252
+ `zeros_like` or `ones_like` instead. It may be marginally faster than
253
+ the functions that do set the array values.
254
+ """
255
+
256
+ a = asarray(a, name=False)
257
+ shape, chunks = _get_like_function_shapes_chunks(a, chunks, shape)
258
+
259
+ # if shape is nan we cannot rely on regular empty function, we use
260
+ # generic map_blocks.
261
+ if np.isnan(shape).any():
262
+ return a.map_blocks(partial(np.empty_like, dtype=(dtype or a.dtype)))
263
+
264
+ return empty(
265
+ shape,
266
+ dtype=(dtype or a.dtype),
267
+ order=order,
268
+ chunks=chunks,
269
+ name=name,
270
+ meta=a._meta,
271
+ )
272
+
273
+
274
+ def ones_like(a, dtype=None, order="C", chunks=None, name=None, shape=None):
275
+ """
276
+ Return an array of ones with the same shape and type as a given array.
277
+
278
+ Parameters
279
+ ----------
280
+ a : array_like
281
+ The shape and data-type of `a` define these same attributes of
282
+ the returned array.
283
+ dtype : data-type, optional
284
+ Overrides the data type of the result.
285
+ order : {'C', 'F'}, optional
286
+ Whether to store multidimensional data in C- or Fortran-contiguous
287
+ (row- or column-wise) order in memory.
288
+ chunks : sequence of ints
289
+ The number of samples on each block. Note that the last block will have
290
+ fewer samples if ``len(array) % chunks != 0``.
291
+ name : str, optional
292
+ An optional keyname for the array. Defaults to hashing the input
293
+ keyword arguments.
294
+ shape : int or sequence of ints, optional.
295
+ Overrides the shape of the result.
296
+
297
+ Returns
298
+ -------
299
+ out : ndarray
300
+ Array of ones with the same shape and type as `a`.
301
+
302
+ See Also
303
+ --------
304
+ zeros_like : Return an array of zeros with shape and type of input.
305
+ empty_like : Return an empty array with shape and type of input.
306
+ zeros : Return a new array setting values to zero.
307
+ ones : Return a new array setting values to one.
308
+ empty : Return a new uninitialized array.
309
+ """
310
+
311
+ a = asarray(a, name=False)
312
+ shape, chunks = _get_like_function_shapes_chunks(a, chunks, shape)
313
+
314
+ # if shape is nan we cannot rely on regular ones function, we use
315
+ # generic map_blocks.
316
+ if np.isnan(shape).any():
317
+ return a.map_blocks(partial(np.ones_like, dtype=(dtype or a.dtype)))
318
+
319
+ return ones(
320
+ shape,
321
+ dtype=(dtype or a.dtype),
322
+ order=order,
323
+ chunks=chunks,
324
+ name=name,
325
+ meta=a._meta,
326
+ )
327
+
328
+
329
+ def zeros_like(a, dtype=None, order="C", chunks=None, name=None, shape=None):
330
+ """
331
+ Return an array of zeros with the same shape and type as a given array.
332
+
333
+ Parameters
334
+ ----------
335
+ a : array_like
336
+ The shape and data-type of `a` define these same attributes of
337
+ the returned array.
338
+ dtype : data-type, optional
339
+ Overrides the data type of the result.
340
+ order : {'C', 'F'}, optional
341
+ Whether to store multidimensional data in C- or Fortran-contiguous
342
+ (row- or column-wise) order in memory.
343
+ chunks : sequence of ints
344
+ The number of samples on each block. Note that the last block will have
345
+ fewer samples if ``len(array) % chunks != 0``.
346
+ name : str, optional
347
+ An optional keyname for the array. Defaults to hashing the input
348
+ keyword arguments.
349
+ shape : int or sequence of ints, optional.
350
+ Overrides the shape of the result.
351
+
352
+ Returns
353
+ -------
354
+ out : ndarray
355
+ Array of zeros with the same shape and type as `a`.
356
+
357
+ See Also
358
+ --------
359
+ ones_like : Return an array of ones with shape and type of input.
360
+ empty_like : Return an empty array with shape and type of input.
361
+ zeros : Return a new array setting values to zero.
362
+ ones : Return a new array setting values to one.
363
+ empty : Return a new uninitialized array.
364
+ """
365
+
366
+ a = asarray(a, name=False)
367
+ shape, chunks = _get_like_function_shapes_chunks(a, chunks, shape)
368
+
369
+ # if shape is nan we cannot rely on regular zeros function, we use
370
+ # generic map_blocks.
371
+ if np.isnan(shape).any():
372
+ return a.map_blocks(partial(np.zeros_like, dtype=(dtype or a.dtype)))
373
+
374
+ return zeros(
375
+ shape,
376
+ dtype=(dtype or a.dtype),
377
+ order=order,
378
+ chunks=chunks,
379
+ name=name,
380
+ meta=a._meta,
381
+ )
382
+
383
+
384
+ def full(shape, fill_value, *args, **kwargs):
385
+ # np.isscalar has somewhat strange behavior:
386
+ # https://docs.scipy.org/doc/numpy/reference/generated/numpy.isscalar.html
387
+ if np.ndim(fill_value) != 0:
388
+ raise ValueError(f"fill_value must be scalar. Received {type(fill_value).__name__} instead.")
389
+ if kwargs.get("dtype") is None:
390
+ if hasattr(fill_value, "dtype"):
391
+ kwargs["dtype"] = fill_value.dtype
392
+ else:
393
+ kwargs["dtype"] = type(fill_value)
394
+ return _full(*args, shape=shape, fill_value=fill_value, **kwargs)
395
+
396
+
397
+ def full_like(a, fill_value, order="C", dtype=None, chunks=None, name=None, shape=None):
398
+ """
399
+ Return a full array with the same shape and type as a given array.
400
+
401
+ Parameters
402
+ ----------
403
+ a : array_like
404
+ The shape and data-type of `a` define these same attributes of
405
+ the returned array.
406
+ fill_value : scalar
407
+ Fill value.
408
+ dtype : data-type, optional
409
+ Overrides the data type of the result.
410
+ order : {'C', 'F'}, optional
411
+ Whether to store multidimensional data in C- or Fortran-contiguous
412
+ (row- or column-wise) order in memory.
413
+ chunks : sequence of ints
414
+ The number of samples on each block. Note that the last block will have
415
+ fewer samples if ``len(array) % chunks != 0``.
416
+ name : str, optional
417
+ An optional keyname for the array. Defaults to hashing the input
418
+ keyword arguments.
419
+ shape : int or sequence of ints, optional.
420
+ Overrides the shape of the result.
421
+
422
+ Returns
423
+ -------
424
+ out : ndarray
425
+ Array of `fill_value` with the same shape and type as `a`.
426
+
427
+ See Also
428
+ --------
429
+ zeros_like : Return an array of zeros with shape and type of input.
430
+ ones_like : Return an array of ones with shape and type of input.
431
+ empty_like : Return an empty array with shape and type of input.
432
+ zeros : Return a new array setting values to zero.
433
+ ones : Return a new array setting values to one.
434
+ empty : Return a new uninitialized array.
435
+ full : Fill a new array.
436
+ """
437
+
438
+ a = asarray(a, name=False)
439
+ shape, chunks = _get_like_function_shapes_chunks(a, chunks, shape)
440
+
441
+ # if shape is nan we cannot rely on regular full function, we use
442
+ # generic map_blocks.
443
+ if np.isnan(shape).any():
444
+ return a.map_blocks(partial(np.full_like, dtype=(dtype or a.dtype)), fill_value)
445
+
446
+ return full(
447
+ shape,
448
+ fill_value,
449
+ dtype=(dtype or a.dtype),
450
+ order=order,
451
+ chunks=chunks,
452
+ name=name,
453
+ meta=a._meta,
454
+ )