1
1
import math
2
+ from collections import Counter
2
3
3
4
from hypothesis import assume , given
4
5
8
9
from . import hypothesis_helpers as hh
9
10
from . import pytest_helpers as ph
10
11
from . import xps
12
+ from .test_searching_functions import assert_default_index
11
13
12
14
13
15
@given (xps .arrays (dtype = xps .scalar_dtypes (), shape = hh .shapes ()))
@@ -16,10 +18,52 @@ def test_unique_all(x):
16
18
# TODO
17
19
18
20
19
- @given (xps .arrays (dtype = xps .scalar_dtypes (), shape = hh .shapes ()))
21
+ @given (xps .arrays (dtype = xps .scalar_dtypes (), shape = hh .shapes (min_side = 1 )))
20
22
def test_unique_counts (x ):
21
- xp .unique_counts (x )
22
- # TODO
23
+ out = xp .unique_counts (x )
24
+ assert hasattr (out , "values" )
25
+ assert hasattr (out , "counts" )
26
+ ph .assert_dtype (
27
+ "unique_counts" , x .dtype , out .values .dtype , repr_name = "out.values.dtype"
28
+ )
29
+ assert_default_index (
30
+ "unique_counts" , out .counts .dtype , repr_name = "out.counts.dtype"
31
+ )
32
+ assert (
33
+ out .counts .shape == out .values .shape
34
+ ), f"{ out .counts .shape = } , but should be { out .values .shape = } "
35
+ scalar_type = dh .get_scalar_type (out .values .dtype )
36
+ counts = Counter (scalar_type (x [idx ]) for idx in ah .ndindex (x .shape ))
37
+ vals_idx = {}
38
+ nans = 0
39
+ for idx in ah .ndindex (out .values .shape ):
40
+ val = scalar_type (out .values [idx ])
41
+ count = int (out .counts [idx ])
42
+ if math .isnan (val ):
43
+ nans += 1
44
+ assert count == 1 , (
45
+ f"out.counts[{ idx } ]={ count } for out.values[{ idx } ]={ val } , "
46
+ "but count should be 1 as NaNs are distinct"
47
+ )
48
+ else :
49
+ expected = counts [val ]
50
+ assert (
51
+ expected > 0
52
+ ), f"out.values[{ idx } ]={ val } , but { val } not in input array"
53
+ count = int (out .counts [idx ])
54
+ assert count == expected , (
55
+ f"out.counts[{ idx } ]={ count } for out.values[{ idx } ]={ val } , "
56
+ f"but should be { expected } "
57
+ )
58
+ assert (
59
+ val not in vals_idx .keys ()
60
+ ), f"out[{ idx } ]={ val } , but { val } is also in out[{ vals_idx [val ]} ]"
61
+ vals_idx [val ] = idx
62
+ if dh .is_float_dtype (out .values .dtype ):
63
+ assume (x .size <= 128 ) # may not be representable
64
+ expected = sum (v for k , v in counts .items () if math .isnan (k ))
65
+ print (f"{ counts = } " )
66
+ assert nans == expected , f"{ nans } NaNs in out, but should be { expected } "
23
67
24
68
25
69
@given (xps .arrays (dtype = xps .scalar_dtypes (), shape = hh .shapes ()))
@@ -48,5 +92,5 @@ def test_unique_values(x):
48
92
vals_idx [val ] = idx
49
93
if dh .is_float_dtype (out .dtype ):
50
94
assume (x .size <= 128 ) # may not be representable
51
- expected_nans = xp .sum (xp .astype (xp .isnan (x ), xp .uint8 ))
52
- assert nans == expected_nans , f"{ nans } NaNs in out, expected { expected_nans } "
95
+ expected = xp .sum (xp .astype (xp .isnan (x ), xp .uint8 ))
96
+ assert nans == expected , f"{ nans } NaNs in out, but should be { expected } "
0 commit comments