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