@@ -171,7 +171,7 @@ class _minmax_mixin:
171
171
These are not implemented for dia_matrix, hence the separate class.
172
172
"""
173
173
174
- def _min_or_max_axis (self , axis , min_or_max ):
174
+ def _min_or_max_axis (self , axis , min_or_max , explicit ):
175
175
N = self .shape [axis ]
176
176
if N == 0 :
177
177
raise ValueError ("zero-size array to reduction operation" )
@@ -182,8 +182,9 @@ def _min_or_max_axis(self, axis, min_or_max):
182
182
mat .sum_duplicates ()
183
183
184
184
major_index , value = mat ._minor_reduce (min_or_max )
185
- not_full = np .diff (mat .indptr )[major_index ] < N
186
- value [not_full ] = min_or_max (value [not_full ], 0 )
185
+ if not explicit :
186
+ not_full = np .diff (mat .indptr )[major_index ] < N
187
+ value [not_full ] = min_or_max (value [not_full ], 0 )
187
188
188
189
mask = value != 0
189
190
major_index = np .compress (mask , major_index )
@@ -205,7 +206,7 @@ def _min_or_max_axis(self, axis, min_or_max):
205
206
dtype = self .dtype , shape = (M , 1 )
206
207
)
207
208
208
- def _min_or_max (self , axis , out , min_or_max ):
209
+ def _min_or_max (self , axis , out , min_or_max , explicit ):
209
210
if out is not None :
210
211
raise ValueError ("Sparse arrays do not support an 'out' parameter." )
211
212
@@ -223,19 +224,19 @@ def _min_or_max(self, axis, out, min_or_max):
223
224
if self .nnz == 0 :
224
225
return zero
225
226
m = min_or_max .reduce (self ._deduped_data ().ravel ())
226
- if self .nnz != math .prod (self .shape ):
227
+ if self .nnz != math .prod (self .shape ) and not explicit :
227
228
m = min_or_max (zero , m )
228
229
return m
229
230
230
231
if axis < 0 :
231
232
axis += 2
232
233
233
234
if (axis == 0 ) or (axis == 1 ):
234
- return self ._min_or_max_axis (axis , min_or_max )
235
+ return self ._min_or_max_axis (axis , min_or_max , explicit )
235
236
else :
236
237
raise ValueError ("axis out of range" )
237
238
238
- def _arg_min_or_max_axis (self , axis , argmin_or_argmax , compare ):
239
+ def _arg_min_or_max_axis (self , axis , argmin_or_argmax , compare , explicit ):
239
240
if self .shape [axis ] == 0 :
240
241
raise ValueError ("Cannot apply the operation along a zero-sized dimension." )
241
242
@@ -257,14 +258,18 @@ def _arg_min_or_max_axis(self, axis, argmin_or_argmax, compare):
257
258
indices = mat .indices [p :q ]
258
259
extreme_index = argmin_or_argmax (data )
259
260
extreme_value = data [extreme_index ]
260
- if compare (extreme_value , zero ) or q - p == line_size :
261
- ret [i ] = indices [extreme_index ]
261
+ if explicit :
262
+ if q - p > 0 :
263
+ ret [i ] = indices [extreme_index ]
262
264
else :
263
- zero_ind = _find_missing_index (indices , line_size )
264
- if extreme_value == zero :
265
- ret [i ] = min (extreme_index , zero_ind )
265
+ if compare (extreme_value , zero ) or q - p == line_size :
266
+ ret [i ] = indices [extreme_index ]
266
267
else :
267
- ret [i ] = zero_ind
268
+ zero_ind = _find_missing_index (indices , line_size )
269
+ if extreme_value == zero :
270
+ ret [i ] = min (extreme_index , zero_ind )
271
+ else :
272
+ ret [i ] = zero_ind
268
273
269
274
if isinstance (self , sparray ):
270
275
return ret
@@ -274,7 +279,7 @@ def _arg_min_or_max_axis(self, axis, argmin_or_argmax, compare):
274
279
275
280
return self ._ascontainer (ret )
276
281
277
- def _arg_min_or_max (self , axis , out , argmin_or_argmax , compare ):
282
+ def _arg_min_or_max (self , axis , out , argmin_or_argmax , compare , explicit ):
278
283
if out is not None :
279
284
raise ValueError ("Sparse types do not support an 'out' parameter." )
280
285
@@ -286,19 +291,24 @@ def _arg_min_or_max(self, axis, out, argmin_or_argmax, compare):
286
291
axis = None # avoid calling special axis case. no impact on 1d
287
292
288
293
if axis is not None :
289
- return self ._arg_min_or_max_axis (axis , argmin_or_argmax , compare )
294
+ return self ._arg_min_or_max_axis (axis , argmin_or_argmax , compare , explicit )
290
295
291
296
if 0 in self .shape :
292
297
raise ValueError ("Cannot apply the operation to an empty matrix." )
293
298
294
299
if self .nnz == 0 :
300
+ if explicit :
301
+ raise ValueError ("Cannot apply the operation to zero matrix "
302
+ "when explicit=True." )
295
303
return 0
296
304
297
305
zero = self .dtype .type (0 )
298
306
mat = self .tocoo ()
299
307
# Convert to canonical form: no duplicates, sorted indices.
300
308
mat .sum_duplicates ()
301
309
extreme_index = argmin_or_argmax (mat .data )
310
+ if explicit :
311
+ return extreme_index
302
312
extreme_value = mat .data [extreme_index ]
303
313
num_col = mat .shape [- 1 ]
304
314
@@ -322,10 +332,11 @@ def _arg_min_or_max(self, axis, out, argmin_or_argmax, compare):
322
332
return min (first_implicit_zero_index , extreme_index )
323
333
return first_implicit_zero_index
324
334
325
- def max (self , axis = None , out = None ):
326
- """
327
- Return the maximum of the array/matrix or maximum along an axis.
328
- This takes all elements into account, not just the non-zero ones.
335
+ def max (self , axis = None , out = None , * , explicit = False ):
336
+ """Return the maximum of the array/matrix or maximum along an axis.
337
+
338
+ By default, all elements are taken into account, not just the non-zero ones.
339
+ But with `explicit` set, only the stored elements are considered.
329
340
330
341
Parameters
331
342
----------
@@ -339,25 +350,33 @@ def max(self, axis=None, out=None):
339
350
compatibility reasons. Do not pass in anything except
340
351
for the default value, as this argument is not used.
341
352
353
+ explicit : {False, True} optional (default: False)
354
+ When set to True, only the stored elements will be considered.
355
+ If a row/column is empty, the sparse.coo_array returned
356
+ has no stored element (i.e. an implicit zero) for that row/column.
357
+
358
+ .. versionadded:: 1.15.0
359
+
342
360
Returns
343
361
-------
344
- amax : coo_matrix or scalar
362
+ amax : coo_array or scalar
345
363
Maximum of `a`. If `axis` is None, the result is a scalar value.
346
- If `axis` is given, the result is a sparse.coo_matrix of dimension
364
+ If `axis` is given, the result is a sparse.coo_array of dimension
347
365
``a.ndim - 1``.
348
366
349
367
See Also
350
368
--------
351
369
min : The minimum value of a sparse array/matrix along a given axis.
352
- numpy.matrix. max : NumPy's implementation of 'max' for matrices
370
+ numpy.max : NumPy's implementation of 'max'
353
371
354
372
"""
355
- return self ._min_or_max (axis , out , np .maximum )
373
+ return self ._min_or_max (axis , out , np .maximum , explicit )
356
374
357
- def min (self , axis = None , out = None ):
358
- """
359
- Return the minimum of the array/matrix or maximum along an axis.
360
- This takes all elements into account, not just the non-zero ones.
375
+ def min (self , axis = None , out = None , * , explicit = False ):
376
+ """Return the minimum of the array/matrix or maximum along an axis.
377
+
378
+ By default, all elements are taken into account, not just the non-zero ones.
379
+ But with `explicit` set, only the stored elements are considered.
361
380
362
381
Parameters
363
382
----------
@@ -371,26 +390,34 @@ def min(self, axis=None, out=None):
371
390
compatibility reasons. Do not pass in anything except for
372
391
the default value, as this argument is not used.
373
392
393
+ explicit : {False, True} optional (default: False)
394
+ When set to True, only the stored elements will be considered.
395
+ If a row/column is empty, the sparse.coo_array returned
396
+ has no stored element (i.e. an implicit zero) for that row/column.
397
+
398
+ .. versionadded:: 1.15.0
399
+
374
400
Returns
375
401
-------
376
402
amin : coo_matrix or scalar
377
403
Minimum of `a`. If `axis` is None, the result is a scalar value.
378
- If `axis` is given, the result is a sparse.coo_matrix of dimension
404
+ If `axis` is given, the result is a sparse.coo_array of dimension
379
405
``a.ndim - 1``.
380
406
381
407
See Also
382
408
--------
383
409
max : The maximum value of a sparse array/matrix along a given axis.
384
- numpy.matrix. min : NumPy's implementation of 'min' for matrices
410
+ numpy.min : NumPy's implementation of 'min'
385
411
386
412
"""
387
- return self ._min_or_max (axis , out , np .minimum )
413
+ return self ._min_or_max (axis , out , np .minimum , explicit )
388
414
389
- def nanmax (self , axis = None , out = None ):
390
- """
391
- Return the maximum of the array/matrix or maximum along an axis, ignoring any
392
- NaNs. This takes all elements into account, not just the non-zero
393
- ones.
415
+ def nanmax (self , axis = None , out = None , * , explicit = False ):
416
+ """Return the maximum, ignoring any Nans, along an axis.
417
+
418
+ Return the maximum, ignoring any Nans, of the array/matrix along an axis.
419
+ By default this takes all elements into account, but with `explicit` set,
420
+ only stored elements are considered.
394
421
395
422
.. versionadded:: 1.11.0
396
423
@@ -406,11 +433,18 @@ def nanmax(self, axis=None, out=None):
406
433
compatibility reasons. Do not pass in anything except
407
434
for the default value, as this argument is not used.
408
435
436
+ explicit : {False, True} optional (default: False)
437
+ When set to True, only the stored elements will be considered.
438
+ If a row/column is empty, the sparse.coo_array returned
439
+ has no stored element (i.e. an implicit zero) for that row/column.
440
+
441
+ .. versionadded:: 1.15.0
442
+
409
443
Returns
410
444
-------
411
- amax : coo_matrix or scalar
445
+ amax : coo_array or scalar
412
446
Maximum of `a`. If `axis` is None, the result is a scalar value.
413
- If `axis` is given, the result is a sparse.coo_matrix of dimension
447
+ If `axis` is given, the result is a sparse.coo_array of dimension
414
448
``a.ndim - 1``.
415
449
416
450
See Also
@@ -422,13 +456,14 @@ def nanmax(self, axis=None, out=None):
422
456
numpy.nanmax : NumPy's implementation of 'nanmax'.
423
457
424
458
"""
425
- return self ._min_or_max (axis , out , np .fmax )
459
+ return self ._min_or_max (axis , out , np .fmax , explicit )
426
460
427
- def nanmin (self , axis = None , out = None ):
428
- """
429
- Return the minimum of the array/matrix or minimum along an axis, ignoring any
430
- NaNs. This takes all elements into account, not just the non-zero
431
- ones.
461
+ def nanmin (self , axis = None , out = None , * , explicit = False ):
462
+ """Return the minimum, ignoring any Nans, along an axis.
463
+
464
+ Return the minimum, ignoring any Nans, of the array/matrix along an axis.
465
+ By default this takes all elements into account, but with `explicit` set,
466
+ only stored elements are considered.
432
467
433
468
.. versionadded:: 1.11.0
434
469
@@ -444,11 +479,18 @@ def nanmin(self, axis=None, out=None):
444
479
compatibility reasons. Do not pass in anything except for
445
480
the default value, as this argument is not used.
446
481
482
+ explicit : {False, True} optional (default: False)
483
+ When set to True, only the stored elements will be considered.
484
+ If a row/column is empty, the sparse.coo_array returned
485
+ has no stored element (i.e. an implicit zero) for that row/column.
486
+
487
+ .. versionadded:: 1.15.0
488
+
447
489
Returns
448
490
-------
449
- amin : coo_matrix or scalar
491
+ amin : coo_array or scalar
450
492
Minimum of `a`. If `axis` is None, the result is a scalar value.
451
- If `axis` is given, the result is a sparse.coo_matrix of dimension
493
+ If `axis` is given, the result is a sparse.coo_array of dimension
452
494
``a.ndim - 1``.
453
495
454
496
See Also
@@ -460,50 +502,68 @@ def nanmin(self, axis=None, out=None):
460
502
numpy.nanmin : NumPy's implementation of 'nanmin'.
461
503
462
504
"""
463
- return self ._min_or_max (axis , out , np .fmin )
505
+ return self ._min_or_max (axis , out , np .fmin , explicit )
464
506
465
- def argmax (self , axis = None , out = None ):
507
+ def argmax (self , axis = None , out = None , * , explicit = False ):
466
508
"""Return indices of maximum elements along an axis.
467
509
468
- Implicit zero elements are also taken into account. If there are
469
- several maximum values, the index of the first occurrence is returned.
510
+ By default, implicit zero elements are taken into account. If there are
511
+ several minimum values, the index of the first occurrence is returned.
512
+ If `explicit` is set, only explicitly stored elements will be considered.
470
513
471
514
Parameters
472
515
----------
473
516
axis : {-2, -1, 0, 1, None}, optional
474
517
Axis along which the argmax is computed. If None (default), index
475
518
of the maximum element in the flatten data is returned.
519
+
476
520
out : None, optional
477
521
This argument is in the signature *solely* for NumPy
478
522
compatibility reasons. Do not pass in anything except for
479
523
the default value, as this argument is not used.
480
524
525
+ explicit : {False, True} optional (default: False)
526
+ When set to True, only explicitly stored elements will be considered.
527
+ If axis is not None and a row/column has no stored elements, argmax
528
+ is undefined, so the index ``0`` is returned for that row/column.
529
+
530
+ .. versionadded:: 1.15.0
531
+
481
532
Returns
482
533
-------
483
534
ind : numpy.matrix or int
484
535
Indices of maximum elements. If matrix, its size along `axis` is 1.
485
536
"""
486
- return self ._arg_min_or_max (axis , out , np .argmax , np .greater )
537
+ return self ._arg_min_or_max (axis , out , np .argmax , np .greater , explicit )
487
538
488
- def argmin (self , axis = None , out = None ):
539
+ def argmin (self , axis = None , out = None , * , explicit = False ):
489
540
"""Return indices of minimum elements along an axis.
490
541
491
- Implicit zero elements are also taken into account. If there are
542
+ By default, implicit zero elements are taken into account. If there are
492
543
several minimum values, the index of the first occurrence is returned.
544
+ If `explicit` is set, only explicitly stored elements will be considered.
493
545
494
546
Parameters
495
547
----------
496
548
axis : {-2, -1, 0, 1, None}, optional
497
549
Axis along which the argmin is computed. If None (default), index
498
550
of the minimum element in the flatten data is returned.
551
+
499
552
out : None, optional
500
553
This argument is in the signature *solely* for NumPy
501
554
compatibility reasons. Do not pass in anything except for
502
555
the default value, as this argument is not used.
503
556
557
+ explicit : {False, True} optional (default: False)
558
+ When set to True, only explicitly stored elements will be considered.
559
+ If axis is not None and a row/column has no stored elements, argmin
560
+ is undefined, so the index ``0`` is returned for that row/column.
561
+
562
+ .. versionadded:: 1.15.0
563
+
504
564
Returns
505
565
-------
506
566
ind : numpy.matrix or int
507
567
Indices of minimum elements. If matrix, its size along `axis` is 1.
508
568
"""
509
- return self ._arg_min_or_max (axis , out , np .argmin , np .less )
569
+ return self ._arg_min_or_max (axis , out , np .argmin , np .less , explicit )
0 commit comments