@@ -1058,64 +1058,49 @@ def putmask(self, mask, new) -> List[Block]:
1058
1058
-------
1059
1059
List[Block]
1060
1060
"""
1061
- transpose = self . ndim == 2
1061
+ orig_mask = mask
1062
1062
mask , noop = validate_putmask (self .values .T , mask )
1063
1063
assert not isinstance (new , (ABCIndex , ABCSeries , ABCDataFrame ))
1064
1064
1065
- new_values = self .values # delay copy if possible.
1066
1065
# if we are passed a scalar None, convert it here
1067
- if not is_list_like (new ) and isna (new ) and not self .is_object :
1068
- # FIXME: make sure we have compatible NA
1066
+ if not self .is_object and is_valid_na_for_dtype (new , self .dtype ):
1069
1067
new = self .fill_value
1070
1068
1071
1069
if self ._can_hold_element (new ):
1072
- if transpose :
1073
- new_values = new_values .T
1074
1070
1075
- putmask_without_repeat (new_values , mask , new )
1071
+ putmask_without_repeat (self . values . T , mask , new )
1076
1072
return [self ]
1077
1073
1078
1074
elif noop :
1079
1075
return [self ]
1080
1076
1081
1077
dtype , _ = infer_dtype_from (new )
1082
1078
if dtype .kind in ["m" , "M" ]:
1083
- # using putmask with object dtype will incorrect cast to object
1079
+ # using putmask with object dtype will incorrectly cast to object
1084
1080
# Having excluded self._can_hold_element, we know we cannot operate
1085
1081
# in-place, so we are safe using `where`
1086
1082
return self .where (new , ~ mask )
1087
1083
1088
- else :
1089
- # may need to upcast
1090
- if transpose :
1091
- mask = mask .T
1092
- if isinstance (new , np .ndarray ):
1093
- new = new .T
1094
-
1095
- # operate column-by-column
1096
- def f (mask , val , idx ):
1097
-
1098
- if idx is None :
1099
- # ndim==1 case.
1100
- n = new
1101
- else :
1102
-
1103
- if isinstance (new , np .ndarray ):
1104
- n = np .squeeze (new [idx % new .shape [0 ]])
1105
- else :
1106
- n = np .array (new )
1107
-
1108
- # type of the new block
1109
- dtype = find_common_type ([n .dtype , val .dtype ])
1110
-
1111
- # we need to explicitly astype here to make a copy
1112
- n = n .astype (dtype )
1113
-
1114
- nv = putmask_smart (val , mask , n )
1115
- return nv
1084
+ elif self .ndim == 1 or self .shape [0 ] == 1 :
1085
+ # no need to split columns
1086
+ nv = putmask_smart (self .values .T , mask , new ).T
1087
+ return [self .make_block (nv )]
1116
1088
1117
- new_blocks = self .split_and_operate (mask , f , True )
1118
- return new_blocks
1089
+ else :
1090
+ is_array = isinstance (new , np .ndarray )
1091
+
1092
+ res_blocks = []
1093
+ nbs = self ._split ()
1094
+ for i , nb in enumerate (nbs ):
1095
+ n = new
1096
+ if is_array :
1097
+ # we have a different value per-column
1098
+ n = new [:, i : i + 1 ]
1099
+
1100
+ submask = orig_mask [:, i : i + 1 ]
1101
+ rbs = nb .putmask (submask , n )
1102
+ res_blocks .extend (rbs )
1103
+ return res_blocks
1119
1104
1120
1105
@final
1121
1106
def coerce_to_target_dtype (self , other ) -> Block :
0 commit comments