@@ -5285,45 +5285,28 @@ def shift(
52855285        axis  =  self ._get_axis_number (axis )
52865286
52875287        ncols  =  len (self .columns )
5288+         if  axis  ==  1  and  periods  !=  0  and  fill_value  is  lib .no_default  and  ncols  >  0 :
5289+             # We will infer fill_value to match the closest column 
52885290
5289-         if  (
5290-             axis  ==  1 
5291-             and  periods  !=  0 
5292-             and  ncols  >  0 
5293-             and  (fill_value  is  lib .no_default  or  len (self ._mgr .arrays ) >  1 )
5294-         ):
5295-             # Exclude single-array-with-fill_value case so we issue a FutureWarning 
5296-             #  if an integer is passed with datetimelike dtype GH#31971 
5297-             from  pandas  import  concat 
5291+             # Use a column that we know is valid for our column's dtype GH#38434 
5292+             label  =  self .columns [0 ]
52985293
5299-             # tail: the data that is still in our shifted DataFrame 
53005294            if  periods  >  0 :
5301-                 tail  =  self .iloc [:, :- periods ]
5302-             else :
5303-                 tail  =  self .iloc [:, - periods :]
5304-             # pin a simple Index to avoid costly casting 
5305-             tail .columns  =  range (len (tail .columns ))
5306- 
5307-             if  fill_value  is  not lib .no_default :
5308-                 # GH#35488 
5309-                 # TODO(EA2D): with 2D EAs we could construct other directly 
5310-                 ser  =  Series (fill_value , index = self .index )
5295+                 result  =  self .iloc [:, :- periods ]
5296+                 for  col  in  range (min (ncols , abs (periods ))):
5297+                     # TODO(EA2D): doing this in a loop unnecessary with 2D EAs 
5298+                     # Define filler inside loop so we get a copy 
5299+                     filler  =  self .iloc [:, 0 ].shift (len (self ))
5300+                     result .insert (0 , label , filler , allow_duplicates = True )
53115301            else :
5312-                 # We infer fill_value to match the closest column 
5313-                 if  periods  >  0 :
5314-                     ser  =  self .iloc [:, 0 ].shift (len (self ))
5315-                 else :
5316-                     ser  =  self .iloc [:, - 1 ].shift (len (self ))
5317- 
5318-             width  =  min (abs (periods ), ncols )
5319-             other  =  concat ([ser ] *  width , axis = 1 )
5320- 
5321-             if  periods  >  0 :
5322-                 result  =  concat ([other , tail ], axis = 1 )
5323-             else :
5324-                 result  =  concat ([tail , other ], axis = 1 )
5302+                 result  =  self .iloc [:, - periods :]
5303+                 for  col  in  range (min (ncols , abs (periods ))):
5304+                     # Define filler inside loop so we get a copy 
5305+                     filler  =  self .iloc [:, - 1 ].shift (len (self ))
5306+                     result .insert (
5307+                         len (result .columns ), label , filler , allow_duplicates = True 
5308+                     )
53255309
5326-             result  =  cast (DataFrame , result )
53275310            result .columns  =  self .columns .copy ()
53285311            return  result 
53295312
0 commit comments