24
24
import pandas .util .testing as tm
25
25
26
26
27
+ @pytest .fixture (params = [True , False , None ])
28
+ def ordered (request ):
29
+ return request .param
30
+
31
+
27
32
class Base (object ):
28
33
29
34
def setup_method (self , method ):
@@ -124,41 +129,6 @@ def test_tuple_categories(self):
124
129
result = CategoricalDtype (categories )
125
130
assert all (result .categories == categories )
126
131
127
- @pytest .mark .parametrize ('dtype' , [
128
- CategoricalDtype (list ('abc' ), False ),
129
- CategoricalDtype (list ('abc' ), True )])
130
- @pytest .mark .parametrize ('new_dtype' , [
131
- 'category' ,
132
- CategoricalDtype (None , False ),
133
- CategoricalDtype (None , True ),
134
- CategoricalDtype (list ('abc' ), False ),
135
- CategoricalDtype (list ('abc' ), True ),
136
- CategoricalDtype (list ('cba' ), False ),
137
- CategoricalDtype (list ('cba' ), True ),
138
- CategoricalDtype (list ('wxyz' ), False ),
139
- CategoricalDtype (list ('wxyz' ), True )])
140
- def test_update_dtype (self , dtype , new_dtype ):
141
- if isinstance (new_dtype , string_types ) and new_dtype == 'category' :
142
- expected_categories = dtype .categories
143
- expected_ordered = dtype .ordered
144
- else :
145
- expected_categories = new_dtype .categories
146
- if expected_categories is None :
147
- expected_categories = dtype .categories
148
- expected_ordered = new_dtype .ordered
149
-
150
- result = dtype ._update_dtype (new_dtype )
151
- tm .assert_index_equal (result .categories , expected_categories )
152
- assert result .ordered is expected_ordered
153
-
154
- @pytest .mark .parametrize ('bad_dtype' , [
155
- 'foo' , object , np .int64 , PeriodDtype ('Q' )])
156
- def test_update_dtype_errors (self , bad_dtype ):
157
- dtype = CategoricalDtype (list ('abc' ), False )
158
- msg = 'a CategoricalDtype must be passed to perform an update, '
159
- with tm .assert_raises_regex (ValueError , msg ):
160
- dtype ._update_dtype (bad_dtype )
161
-
162
132
163
133
class TestDatetimeTZDtype (Base ):
164
134
@@ -609,39 +579,37 @@ def test_caching(self):
609
579
610
580
class TestCategoricalDtypeParametrized (object ):
611
581
612
- @pytest .mark .parametrize ('categories, ordered' , [
613
- (['a' , 'b' , 'c' , 'd' ], False ),
614
- (['a' , 'b' , 'c' , 'd' ], True ),
615
- (np .arange (1000 ), False ),
616
- (np .arange (1000 ), True ),
617
- (['a' , 'b' , 10 , 2 , 1.3 , True ], False ),
618
- ([True , False ], True ),
619
- ([True , False ], False ),
620
- (pd .date_range ('2017' , periods = 4 ), True ),
621
- (pd .date_range ('2017' , periods = 4 ), False ),
622
- ])
582
+ @pytest .mark .parametrize ('categories' , [
583
+ list ('abcd' ),
584
+ np .arange (1000 ),
585
+ ['a' , 'b' , 10 , 2 , 1.3 , True ],
586
+ [True , False ],
587
+ pd .date_range ('2017' , periods = 4 )])
623
588
def test_basic (self , categories , ordered ):
624
589
c1 = CategoricalDtype (categories , ordered = ordered )
625
590
tm .assert_index_equal (c1 .categories , pd .Index (categories ))
626
591
assert c1 .ordered is ordered
627
592
628
593
def test_order_matters (self ):
629
594
categories = ['a' , 'b' ]
630
- c1 = CategoricalDtype (categories , ordered = False )
631
- c2 = CategoricalDtype (categories , ordered = True )
595
+ c1 = CategoricalDtype (categories , ordered = True )
596
+ c2 = CategoricalDtype (categories , ordered = False )
597
+ c3 = CategoricalDtype (categories , ordered = None )
632
598
assert c1 is not c2
599
+ assert c1 is not c3
633
600
634
- def test_unordered_same (self ):
635
- c1 = CategoricalDtype (['a' , 'b' ])
636
- c2 = CategoricalDtype (['b' , 'a' ])
601
+ @pytest .mark .parametrize ('ordered' , [False , None ])
602
+ def test_unordered_same (self , ordered ):
603
+ c1 = CategoricalDtype (['a' , 'b' ], ordered = ordered )
604
+ c2 = CategoricalDtype (['b' , 'a' ], ordered = ordered )
637
605
assert hash (c1 ) == hash (c2 )
638
606
639
607
def test_categories (self ):
640
608
result = CategoricalDtype (['a' , 'b' , 'c' ])
641
609
tm .assert_index_equal (result .categories , pd .Index (['a' , 'b' , 'c' ]))
642
- assert result .ordered is False
610
+ assert result .ordered is None
643
611
644
- def test_equal_but_different (self ):
612
+ def test_equal_but_different (self , ordered ):
645
613
c1 = CategoricalDtype ([1 , 2 , 3 ])
646
614
c2 = CategoricalDtype ([1. , 2. , 3. ])
647
615
assert c1 is not c2
@@ -652,9 +620,11 @@ def test_equal_but_different(self):
652
620
([1 , 2 , 3 ], [3 , 2 , 1 ]),
653
621
])
654
622
def test_order_hashes_different (self , v1 , v2 ):
655
- c1 = CategoricalDtype (v1 )
623
+ c1 = CategoricalDtype (v1 , ordered = False )
656
624
c2 = CategoricalDtype (v2 , ordered = True )
625
+ c3 = CategoricalDtype (v1 , ordered = None )
657
626
assert c1 is not c2
627
+ assert c1 is not c3
658
628
659
629
def test_nan_invalid (self ):
660
630
with pytest .raises (ValueError ):
@@ -669,26 +639,35 @@ def test_same_categories_different_order(self):
669
639
c2 = CategoricalDtype (['b' , 'a' ], ordered = True )
670
640
assert c1 is not c2
671
641
672
- @pytest .mark .parametrize ('ordered, other, expected' , [
673
- (True , CategoricalDtype (['a' , 'b' ], True ), True ),
674
- (False , CategoricalDtype (['a' , 'b' ], False ), True ),
675
- (True , CategoricalDtype (['a' , 'b' ], False ), False ),
676
- (False , CategoricalDtype (['a' , 'b' ], True ), False ),
677
- (True , CategoricalDtype ([1 , 2 ], False ), False ),
678
- (False , CategoricalDtype ([1 , 2 ], True ), False ),
679
- (False , CategoricalDtype (None , True ), True ),
680
- (True , CategoricalDtype (None , True ), True ),
681
- (False , CategoricalDtype (None , False ), True ),
682
- (True , CategoricalDtype (None , False ), True ),
683
- (True , 'category' , True ),
684
- (False , 'category' , True ),
685
- (True , 'not a category' , False ),
686
- (False , 'not a category' , False ),
687
- ])
688
- def test_categorical_equality (self , ordered , other , expected ):
689
- c1 = CategoricalDtype (['a' , 'b' ], ordered )
642
+ @pytest .mark .parametrize ('ordered1' , [True , False , None ])
643
+ @pytest .mark .parametrize ('ordered2' , [True , False , None ])
644
+ def test_categorical_equality (self , ordered1 , ordered2 ):
645
+ # same categories
646
+ c1 = CategoricalDtype (list ('abc' ), ordered1 )
647
+ c2 = CategoricalDtype (list ('abc' ), ordered2 )
648
+ result = c1 == c2
649
+ expected = (ordered1 is ordered2 ) or not any ([ordered1 , ordered2 ])
650
+ assert result is expected
651
+
652
+ # different categories
653
+ c2 = CategoricalDtype ([1 , 2 , 3 ], ordered2 )
654
+ assert c1 != c2
655
+
656
+ # none categories
657
+ c1 = CategoricalDtype (list ('abc' ), ordered1 )
658
+ c2 = CategoricalDtype (None , ordered2 )
659
+ c3 = CategoricalDtype (None , ordered1 )
660
+ assert c1 == c2
661
+ assert c2 == c1
662
+ assert c2 == c3
663
+
664
+ @pytest .mark .parametrize ('categories' , [list ('abc' ), None ])
665
+ @pytest .mark .parametrize ('other' , ['category' , 'not a category' ])
666
+ def test_categorical_equality_strings (self , categories , ordered , other ):
667
+ c1 = CategoricalDtype (categories , ordered )
690
668
result = c1 == other
691
- assert result == expected
669
+ expected = other == 'category'
670
+ assert result is expected
692
671
693
672
def test_invalid_raises (self ):
694
673
with tm .assert_raises_regex (TypeError , 'ordered' ):
@@ -729,16 +708,51 @@ def test_from_categorical_dtype_both(self):
729
708
c1 , categories = [1 , 2 ], ordered = False )
730
709
assert result == CategoricalDtype ([1 , 2 ], ordered = False )
731
710
732
- def test_str_vs_repr (self ):
733
- c1 = CategoricalDtype (['a' , 'b' ])
711
+ def test_str_vs_repr (self , ordered ):
712
+ c1 = CategoricalDtype (['a' , 'b' ], ordered = ordered )
734
713
assert str (c1 ) == 'category'
735
714
# Py2 will have unicode prefixes
736
- pat = r"CategoricalDtype\(categories=\[.*\], ordered=False \)"
737
- assert re .match (pat , repr (c1 ))
715
+ pat = r"CategoricalDtype\(categories=\[.*\], ordered={ordered} \)"
716
+ assert re .match (pat . format ( ordered = ordered ) , repr (c1 ))
738
717
739
718
def test_categorical_categories (self ):
740
719
# GH17884
741
720
c1 = CategoricalDtype (Categorical (['a' , 'b' ]))
742
721
tm .assert_index_equal (c1 .categories , pd .Index (['a' , 'b' ]))
743
722
c1 = CategoricalDtype (CategoricalIndex (['a' , 'b' ]))
744
723
tm .assert_index_equal (c1 .categories , pd .Index (['a' , 'b' ]))
724
+
725
+ @pytest .mark .parametrize ('new_categories' , [
726
+ list ('abc' ), list ('cba' ), list ('wxyz' ), None ])
727
+ @pytest .mark .parametrize ('new_ordered' , [True , False , None ])
728
+ def test_update_dtype (self , ordered , new_categories , new_ordered ):
729
+ dtype = CategoricalDtype (list ('abc' ), ordered )
730
+ new_dtype = CategoricalDtype (new_categories , new_ordered )
731
+
732
+ expected_categories = new_dtype .categories
733
+ if expected_categories is None :
734
+ expected_categories = dtype .categories
735
+
736
+ expected_ordered = new_dtype .ordered
737
+ if expected_ordered is None :
738
+ expected_ordered = dtype .ordered
739
+
740
+ result = dtype ._update_dtype (new_dtype )
741
+ tm .assert_index_equal (result .categories , expected_categories )
742
+ assert result .ordered is expected_ordered
743
+
744
+ def test_update_dtype_string (self , ordered ):
745
+ dtype = CategoricalDtype (list ('abc' ), ordered )
746
+ expected_categories = dtype .categories
747
+ expected_ordered = dtype .ordered
748
+ result = dtype ._update_dtype ('category' )
749
+ tm .assert_index_equal (result .categories , expected_categories )
750
+ assert result .ordered is expected_ordered
751
+
752
+ @pytest .mark .parametrize ('bad_dtype' , [
753
+ 'foo' , object , np .int64 , PeriodDtype ('Q' )])
754
+ def test_update_dtype_errors (self , bad_dtype ):
755
+ dtype = CategoricalDtype (list ('abc' ), False )
756
+ msg = 'a CategoricalDtype must be passed to perform an update, '
757
+ with tm .assert_raises_regex (ValueError , msg ):
758
+ dtype ._update_dtype (bad_dtype )
0 commit comments