@@ -389,12 +389,7 @@ def fillna(self, value, limit=None, inplace=False, downcast=None,
389
389
blocks = [b .make_block (values = self ._try_coerce_result (b .values ))
390
390
for b in blocks ]
391
391
return self ._maybe_downcast (blocks , downcast )
392
- except (TypeError , ValueError ) as e :
393
-
394
- if self .is_timedelta :
395
- raise AssertionError (
396
- "causing recursion error: {} {} {} {}" .format (
397
- self , value , type (value ), e ))
392
+ except (TypeError , ValueError ):
398
393
399
394
# we can't process the value, but nothing to do
400
395
if not mask .any ():
@@ -431,6 +426,8 @@ def split_and_operate(self, mask, f, inplace):
431
426
list of blocks
432
427
"""
433
428
429
+ if mask is None :
430
+ mask = np .ones (self .shape , dtype = bool )
434
431
new_values = self .values
435
432
436
433
def make_a_block (nv , ref_loc ):
@@ -441,7 +438,10 @@ def make_a_block(nv, ref_loc):
441
438
else :
442
439
# Put back the dimension that was taken from it and make
443
440
# a block out of the result.
444
- nv = _block_shape (nv , ndim = self .ndim )
441
+ try :
442
+ nv = _block_shape (nv , ndim = self .ndim )
443
+ except (AttributeError , NotImplementedError ):
444
+ pass
445
445
block = self .make_block (values = nv ,
446
446
placement = ref_loc , fastpath = True )
447
447
return block
@@ -512,27 +512,20 @@ def downcast(self, dtypes=None, mgr=None):
512
512
raise ValueError ("downcast must have a dictionary or 'infer' as "
513
513
"its argument" )
514
514
515
- # item -by-item
515
+ # operate column -by-column
516
516
# this is expensive as it splits the blocks items-by-item
517
- blocks = []
518
- for i , rl in enumerate (self .mgr_locs ):
517
+ def f (m , v , i ):
519
518
520
519
if dtypes == 'infer' :
521
520
dtype = 'infer'
522
521
else :
523
522
raise AssertionError ("dtypes as dict is not supported yet" )
524
- # TODO: This either should be completed or removed
525
- dtype = dtypes .get (item , self ._downcast_dtype ) # noqa
526
523
527
- if dtype is None :
528
- nv = _block_shape (values [i ], ndim = self .ndim )
529
- else :
530
- nv = maybe_downcast_to_dtype (values [i ], dtype )
531
- nv = _block_shape (nv , ndim = self .ndim )
532
-
533
- blocks .append (self .make_block (nv , fastpath = True , placement = [rl ]))
524
+ if dtype is not None :
525
+ v = maybe_downcast_to_dtype (v , dtype )
526
+ return v
534
527
535
- return blocks
528
+ return self . split_and_operate ( None , f , False )
536
529
537
530
def astype (self , dtype , copy = False , errors = 'raise' , values = None , ** kwargs ):
538
531
return self ._astype (dtype , copy = copy , errors = errors , values = values ,
@@ -655,10 +648,6 @@ def _try_cast_result(self, result, dtype=None):
655
648
# may need to change the dtype here
656
649
return maybe_downcast_to_dtype (result , dtype )
657
650
658
- def _try_operate (self , values ):
659
- """ return a version to operate on as the input """
660
- return values
661
-
662
651
def _try_coerce_args (self , values , other ):
663
652
""" provide coercion to our input arguments """
664
653
@@ -680,9 +669,6 @@ def _try_coerce_and_cast_result(self, result, dtype=None):
680
669
result = self ._try_cast_result (result , dtype = dtype )
681
670
return result
682
671
683
- def _try_fill (self , value ):
684
- return value
685
-
686
672
def to_native_types (self , slicer = None , na_rep = 'nan' , quoting = None ,
687
673
** kwargs ):
688
674
""" convert to our native types format, slicing if desired """
@@ -1120,7 +1106,6 @@ def _interpolate_with_fill(self, method='pad', axis=0, inplace=False,
1120
1106
1121
1107
values = self .values if inplace else self .values .copy ()
1122
1108
values , _ , fill_value , _ = self ._try_coerce_args (values , fill_value )
1123
- values = self ._try_operate (values )
1124
1109
values = missing .interpolate_2d (values , method = method , axis = axis ,
1125
1110
limit = limit , fill_value = fill_value ,
1126
1111
dtype = self .dtype )
@@ -1834,10 +1819,6 @@ def _na_value(self):
1834
1819
def fill_value (self ):
1835
1820
return tslib .iNaT
1836
1821
1837
- def _try_operate (self , values ):
1838
- """ return a version to operate on """
1839
- return values .view ('i8' )
1840
-
1841
1822
def get_values (self , dtype = None ):
1842
1823
"""
1843
1824
return object dtype as boxed values, such as Timestamps/Timedelta
@@ -2031,31 +2012,24 @@ def convert(self, *args, **kwargs):
2031
2012
if key in kwargs :
2032
2013
fn_kwargs [key ] = kwargs [key ]
2033
2014
2034
- # attempt to create new type blocks
2035
- blocks = []
2036
- if by_item and not self ._is_single_block :
2037
-
2038
- for i , rl in enumerate (self .mgr_locs ):
2039
- values = self .iget (i )
2015
+ # operate column-by-column
2016
+ def f (m , v , i ):
2017
+ shape = v .shape
2018
+ values = fn (v .ravel (), ** fn_kwargs )
2019
+ try :
2020
+ values = values .reshape (shape )
2021
+ values = _block_shape (values , ndim = self .ndim )
2022
+ except (AttributeError , NotImplementedError ):
2023
+ pass
2040
2024
2041
- shape = values .shape
2042
- values = fn (values .ravel (), ** fn_kwargs )
2043
- try :
2044
- values = values .reshape (shape )
2045
- values = _block_shape (values , ndim = self .ndim )
2046
- except (AttributeError , NotImplementedError ):
2047
- pass
2048
- newb = make_block (values , ndim = self .ndim , placement = [rl ])
2049
- blocks .append (newb )
2025
+ return values
2050
2026
2027
+ if by_item and not self ._is_single_block :
2028
+ blocks = self .split_and_operate (None , f , False )
2051
2029
else :
2052
- values = fn (self .values .ravel (), ** fn_kwargs )
2053
- try :
2054
- values = values .reshape (self .values .shape )
2055
- except NotImplementedError :
2056
- pass
2057
- blocks .append (make_block (values , ndim = self .ndim ,
2058
- placement = self .mgr_locs ))
2030
+ values = f (None , self .values .ravel (), None )
2031
+ blocks = [make_block (values , ndim = self .ndim ,
2032
+ placement = self .mgr_locs )]
2059
2033
2060
2034
return blocks
2061
2035
@@ -4878,17 +4852,30 @@ def _transform_index(index, func, level=None):
4878
4852
4879
4853
def _putmask_smart (v , m , n ):
4880
4854
"""
4881
- Return a new block , try to preserve dtype if possible.
4855
+ Return a new ndarray , try to preserve dtype if possible.
4882
4856
4883
4857
Parameters
4884
4858
----------
4885
4859
v : `values`, updated in-place (array like)
4886
4860
m : `mask`, applies to both sides (array like)
4887
4861
n : `new values` either scalar or an array like aligned with `values`
4862
+
4863
+ Returns
4864
+ -------
4865
+ values : ndarray with updated values
4866
+ this *may* be a copy of the original
4867
+
4868
+ See Also
4869
+ --------
4870
+ ndarray.putmask
4888
4871
"""
4872
+
4873
+ # we cannot use np.asarray() here as we cannot have conversions
4874
+ # that numpy does when numeric are mixed with strings
4875
+
4889
4876
# n should be the length of the mask or a scalar here
4890
4877
if not is_list_like (n ):
4891
- n = np .array ([ n ] * len (m ))
4878
+ n = np .repeat ( n , len (m ))
4892
4879
elif isinstance (n , np .ndarray ) and n .ndim == 0 : # numpy scalar
4893
4880
n = np .repeat (np .array (n , ndmin = 1 ), len (m ))
4894
4881
@@ -4907,56 +4894,46 @@ def _putmask_smart(v, m, n):
4907
4894
nn_at = nn .astype (v .dtype )
4908
4895
4909
4896
# avoid invalid dtype comparisons
4910
- if not is_numeric_v_string_like (nn , nn_at ):
4911
-
4912
- # only compare integers/floats
4913
- # don't compare integers to datetimelikes
4914
- if (is_float_dtype (nn .dtype ) or
4915
- is_integer_dtype (nn .dtype ) and
4916
- is_float_dtype (nn_at .dtype ) or
4917
- is_integer_dtype (nn_at .dtype )):
4918
- comp = (nn == nn_at )
4919
- if is_list_like (comp ) and comp .all ():
4920
- nv = v .copy ()
4921
- nv [m ] = nn_at
4922
- return nv
4897
+ # between numbers & strings
4898
+
4899
+ # only compare integers/floats
4900
+ # don't compare integers to datetimelikes
4901
+ if (not is_numeric_v_string_like (nn , nn_at ) and
4902
+ (is_float_dtype (nn .dtype ) or
4903
+ is_integer_dtype (nn .dtype ) and
4904
+ is_float_dtype (nn_at .dtype ) or
4905
+ is_integer_dtype (nn_at .dtype ))):
4906
+
4907
+ comp = (nn == nn_at )
4908
+ if is_list_like (comp ) and comp .all ():
4909
+ nv = v .copy ()
4910
+ nv [m ] = nn_at
4911
+ return nv
4923
4912
except (ValueError , IndexError , TypeError ):
4924
4913
pass
4925
4914
4926
4915
n = np .asarray (n )
4927
4916
4928
- # preserves dtype if possible
4929
- if v .dtype .kind == n .dtype .kind :
4917
+ def _putmask_preserve (nv , n ):
4930
4918
try :
4931
- v [m ] = n [m ]
4932
- return v
4933
- except :
4934
- pass
4919
+ nv [m ] = n [m ]
4920
+ except ( IndexError , ValueError ):
4921
+ nv [ m ] = n
4922
+ return nv
4935
4923
4936
- try :
4937
- v [m ] = n
4938
- return v
4939
- except :
4940
- pass
4924
+ # preserves dtype if possible
4925
+ if v .dtype .kind == n .dtype .kind :
4926
+ return _putmask_preserve (v , n )
4941
4927
4942
4928
# change the dtype if needed
4943
4929
dtype , _ = maybe_promote (n .dtype )
4944
4930
4945
4931
if is_extension_type (v .dtype ) and is_object_dtype (dtype ):
4946
- nv = v .get_values (dtype )
4932
+ v = v .get_values (dtype )
4947
4933
else :
4948
- nv = v .astype (dtype )
4934
+ v = v .astype (dtype )
4949
4935
4950
- try :
4951
- nv [m ] = n [m ]
4952
- except ValueError :
4953
- idx , = np .where (np .squeeze (m ))
4954
- for mask_index , new_val in zip (idx , n ):
4955
- nv [mask_index ] = new_val
4956
- except IndexError :
4957
- nv [m ] = n
4958
-
4959
- return nv
4936
+ return _putmask_preserve (v , n )
4960
4937
4961
4938
4962
4939
def concatenate_block_managers (mgrs_indexers , axes , concat_axis , copy ):
0 commit comments