@@ -394,14 +394,22 @@ def __init__(self, data=None, index=None, columns=None, dtype=None,
394394 elif isinstance (data , dict ):
395395 mgr = self ._init_dict (data , index , columns , dtype = dtype )
396396 elif isinstance (data , ma .MaskedArray ):
397- mask = ma .getmaskarray (data )
398- if mask .any ():
399- data , fill_value = _maybe_upcast (data , copy = True )
400- data [mask ] = fill_value
397+
398+ # masked recarray
399+ if isinstance (data , ma .mrecords .MaskedRecords ):
400+ mgr = _masked_rec_array_to_mgr (data , index , columns , dtype , copy )
401+
402+ # a masked array
401403 else :
402- data = data .copy ()
403- mgr = self ._init_ndarray (data , index , columns , dtype = dtype ,
404- copy = copy )
404+ mask = ma .getmaskarray (data )
405+ if mask .any ():
406+ data , fill_value = _maybe_upcast (data , copy = True )
407+ data [mask ] = fill_value
408+ else :
409+ data = data .copy ()
410+ mgr = self ._init_ndarray (data , index , columns , dtype = dtype ,
411+ copy = copy )
412+
405413 elif isinstance (data , (np .ndarray , Series )):
406414 if data .dtype .names :
407415 data_columns = list (data .dtype .names )
@@ -1009,13 +1017,7 @@ def from_records(cls, data, index=None, exclude=None, columns=None,
10091017 arr_columns .append (k )
10101018 arrays .append (v )
10111019
1012- # reorder according to the columns
1013- if len (columns ) and len (arr_columns ):
1014- indexer = _ensure_index (
1015- arr_columns ).get_indexer (columns )
1016- arr_columns = _ensure_index (
1017- [arr_columns [i ] for i in indexer ])
1018- arrays = [arrays [i ] for i in indexer ]
1020+ arrays , arr_columns = _reorder_arrays (arrays , arr_columns , columns )
10191021
10201022 elif isinstance (data , (np .ndarray , DataFrame )):
10211023 arrays , columns = _to_arrays (data , columns )
@@ -4817,6 +4819,52 @@ def _to_arrays(data, columns, coerce_float=False, dtype=None):
48174819 dtype = dtype )
48184820
48194821
4822+ def _masked_rec_array_to_mgr (data , index , columns , dtype , copy ):
4823+ """ extract from a masked rec array and create the manager """
4824+
4825+ # essentially process a record array then fill it
4826+ fill_value = data .fill_value
4827+ fdata = ma .getdata (data )
4828+ if index is None :
4829+ index = _get_names_from_index (fdata )
4830+ if index is None :
4831+ index = _default_index (len (data ))
4832+ index = _ensure_index (index )
4833+
4834+ if columns is not None :
4835+ columns = _ensure_index (columns )
4836+ arrays , arr_columns = _to_arrays (fdata , columns )
4837+
4838+ # fill if needed
4839+ new_arrays = []
4840+ for fv , arr , col in zip (fill_value , arrays , arr_columns ):
4841+ mask = ma .getmaskarray (data [col ])
4842+ if mask .any ():
4843+ arr , fv = _maybe_upcast (arr , fill_value = fv , copy = True )
4844+ arr [mask ] = fv
4845+ new_arrays .append (arr )
4846+
4847+ # create the manager
4848+ arrays , arr_columns = _reorder_arrays (new_arrays , arr_columns , columns )
4849+ if columns is None :
4850+ columns = arr_columns
4851+
4852+ mgr = _arrays_to_mgr (arrays , arr_columns , index , columns )
4853+
4854+ if copy :
4855+ mgr = mgr .copy ()
4856+ return mgr
4857+
4858+ def _reorder_arrays (arrays , arr_columns , columns ):
4859+ # reorder according to the columns
4860+ if columns is not None and len (columns ) and arr_columns is not None and len (arr_columns ):
4861+ indexer = _ensure_index (
4862+ arr_columns ).get_indexer (columns )
4863+ arr_columns = _ensure_index (
4864+ [arr_columns [i ] for i in indexer ])
4865+ arrays = [arrays [i ] for i in indexer ]
4866+ return arrays , arr_columns
4867+
48204868def _list_to_arrays (data , columns , coerce_float = False , dtype = None ):
48214869 if len (data ) > 0 and isinstance (data [0 ], tuple ):
48224870 content = list (lib .to_object_array_tuples (data ).T )
0 commit comments