@@ -550,6 +550,40 @@ def test_apply_axis(self):
550
550
result ._compute ()
551
551
assert result .ctx == expected
552
552
553
+ @pytest .mark .parametrize ("axis" , [0 , 1 ])
554
+ def test_apply_series_return (self , axis ):
555
+ # GH 42014
556
+ df = DataFrame ([[1 , 2 ], [3 , 4 ]], index = ["X" , "Y" ], columns = ["X" , "Y" ])
557
+
558
+ # test Series return where len(Series) < df.index or df.columns but labels OK
559
+ func = lambda s : pd .Series (["color: red;" ], index = ["Y" ])
560
+ result = df .style .apply (func , axis = axis )._compute ().ctx
561
+ assert result [(1 , 1 )] == [("color" , "red" )]
562
+ assert result [(1 - axis , axis )] == [("color" , "red" )]
563
+
564
+ # test Series return where labels align but different order
565
+ func = lambda s : pd .Series (["color: red;" , "color: blue;" ], index = ["Y" , "X" ])
566
+ result = df .style .apply (func , axis = axis )._compute ().ctx
567
+ assert result [(0 , 0 )] == [("color" , "blue" )]
568
+ assert result [(1 , 1 )] == [("color" , "red" )]
569
+ assert result [(1 - axis , axis )] == [("color" , "red" )]
570
+ assert result [(axis , 1 - axis )] == [("color" , "blue" )]
571
+
572
+ @pytest .mark .parametrize ("index" , [False , True ])
573
+ @pytest .mark .parametrize ("columns" , [False , True ])
574
+ def test_apply_dataframe_return (self , index , columns ):
575
+ # GH 42014
576
+ df = DataFrame ([[1 , 2 ], [3 , 4 ]], index = ["X" , "Y" ], columns = ["X" , "Y" ])
577
+ idxs = ["X" , "Y" ] if index else ["Y" ]
578
+ cols = ["X" , "Y" ] if columns else ["Y" ]
579
+ df_styles = DataFrame ("color: red;" , index = idxs , columns = cols )
580
+ result = df .style .apply (lambda x : df_styles , axis = None )._compute ().ctx
581
+
582
+ assert result [(1 , 1 )] == [("color" , "red" )] # (Y,Y) styles always present
583
+ assert (result [(0 , 1 )] == [("color" , "red" )]) is index # (X,Y) only if index
584
+ assert (result [(1 , 0 )] == [("color" , "red" )]) is columns # (Y,X) only if cols
585
+ assert (result [(0 , 0 )] == [("color" , "red" )]) is (index and columns ) # (X,X)
586
+
553
587
@pytest .mark .parametrize (
554
588
"slice_" ,
555
589
[
@@ -794,24 +828,28 @@ def test_export(self):
794
828
style2 .to_html ()
795
829
796
830
def test_bad_apply_shape (self ):
797
- df = DataFrame ([[1 , 2 ], [3 , 4 ]])
798
- msg = "returned the wrong shape"
799
- with pytest .raises (ValueError , match = msg ):
800
- df .style ._apply (lambda x : "x" , subset = pd .IndexSlice [[0 , 1 ], :])
831
+ df = DataFrame ([[1 , 2 ], [3 , 4 ]], index = ["A" , "B" ], columns = ["X" , "Y" ])
801
832
833
+ msg = "resulted in the apply method collapsing to a Series."
802
834
with pytest .raises (ValueError , match = msg ):
803
- df .style ._apply (lambda x : [ "" ], subset = pd . IndexSlice [[ 0 , 1 ], :] )
835
+ df .style ._apply (lambda x : "x" )
804
836
805
- with pytest .raises (ValueError , match = msg ):
837
+ msg = "created invalid {} labels"
838
+ with pytest .raises (ValueError , match = msg .format ("index" )):
839
+ df .style ._apply (lambda x : ["" ])
840
+
841
+ with pytest .raises (ValueError , match = msg .format ("index" )):
806
842
df .style ._apply (lambda x : ["" , "" , "" , "" ])
807
843
808
- with pytest .raises (ValueError , match = msg ):
809
- df .style ._apply (lambda x : [ " " , "" , "" ], subset = 1 )
844
+ with pytest .raises (ValueError , match = msg . format ( "index" ) ):
845
+ df .style ._apply (lambda x : pd . Series ([ "a:v; " , "" ], index = [ "A" , "C" ]), axis = 0 )
810
846
811
- msg = "Length mismatch: Expected axis has 3 elements"
812
- with pytest .raises (ValueError , match = msg ):
847
+ with pytest .raises (ValueError , match = msg .format ("columns" )):
813
848
df .style ._apply (lambda x : ["" , "" , "" ], axis = 1 )
814
849
850
+ with pytest .raises (ValueError , match = msg .format ("columns" )):
851
+ df .style ._apply (lambda x : pd .Series (["a:v;" , "" ], index = ["X" , "Z" ]), axis = 1 )
852
+
815
853
msg = "returned ndarray with wrong shape"
816
854
with pytest .raises (ValueError , match = msg ):
817
855
df .style ._apply (lambda x : np .array ([["" ], ["" ]]), axis = None )
@@ -828,12 +866,13 @@ def f(x):
828
866
with pytest .raises (TypeError , match = msg ):
829
867
df .style ._apply (f , axis = None )
830
868
831
- def test_apply_bad_labels (self ):
869
+ @pytest .mark .parametrize ("axis" , ["index" , "columns" ])
870
+ def test_apply_bad_labels (self , axis ):
832
871
def f (x ):
833
- return DataFrame (index = [ 1 , 2 ], columns = [ "a " , "b" ] )
872
+ return DataFrame (** { axis : [ "bad " , "labels" ]} )
834
873
835
874
df = DataFrame ([[1 , 2 ], [3 , 4 ]])
836
- msg = "must have identical index and columns as the input "
875
+ msg = f"created invalid { axis } labels. "
837
876
with pytest .raises (ValueError , match = msg ):
838
877
df .style ._apply (f , axis = None )
839
878
0 commit comments