def fillna(self: BaseMaskedArrayT, value=None, method=None, limit=None) -> BaseMaskedArrayT: value, method = validate_fillna_kwargs(value, method) mask = self._mask if is_array_like(value): if len(value) != len(self): raise ValueError( f"Length of 'value' does not match. Got ({len(value)}) " f" expected {len(self)}") value = value[mask] if mask.any(): if method is not None: func = missing.get_fill_func(method) new_values, new_mask = func( self._data.copy(), limit=limit, mask=mask.copy(), ) return type(self)(new_values, new_mask.view(np.bool_)) else: # fill with value new_values = self.copy() new_values[mask] = value else: new_values = self.copy() return new_values
def __setitem__(self, key, value): value = extract_array(value, extract_numpy=True) if isinstance(value, type(self)): # extract_array doesn't extract PandasArray subclasses value = value._ndarray key = check_array_indexer(self, key) scalar_key = lib.is_scalar(key) scalar_value = lib.is_scalar(value) if scalar_key and not scalar_value: raise ValueError("setting an array element with a sequence.") # validate new items if scalar_value: if isna(value): value = StringDtype.na_value elif not isinstance(value, str): raise ValueError( f"Cannot set non-string value '{value}' into a StringArray." ) else: if not is_array_like(value): value = np.asarray(value, dtype=object) if len(value) and not lib.is_string_array(value, skipna=True): raise ValueError("Must provide strings.") super().__setitem__(key, value)
def fillna(self, value=None, method=None, limit=None): # TODO(_values_for_fillna): remove this value, method = validate_fillna_kwargs(value, method) mask = self.isna() if is_array_like(value): if len(value) != len(self): raise ValueError("Length of 'value' does not match. Got ({}) " " expected {}".format(len(value), len(self))) value = value[mask] if mask.any(): if method is not None: func = pad_1d if method == 'pad' else backfill_1d new_values = func(self._ndarray, limit=limit, mask=mask) new_values = self._from_sequence(new_values, dtype=self.dtype) else: # fill with value new_values = self.copy() new_values[mask] = value else: new_values = self.copy() return new_values
def fillna(self: NDArrayBackedExtensionArrayT, value=None, method=None, limit=None) -> NDArrayBackedExtensionArrayT: value, method = validate_fillna_kwargs(value, method) mask = self.isna() # TODO: share this with EA base class implementation if is_array_like(value): if len(value) != len(self): raise ValueError( f"Length of 'value' does not match. Got ({len(value)}) " f" expected {len(self)}") value = value[mask] if mask.any(): if method is not None: func = missing.get_fill_func(method) new_values = func(self._ndarray.copy(), limit=limit, mask=mask) # TODO: PandasArray didn't used to copy, need tests for this new_values = self._from_backing_data(new_values) else: # fill with value new_values = self.copy() new_values[mask] = value else: new_values = self.copy() return new_values
def fillna(self, value=None, method=None, limit=None): # TODO(_values_for_fillna): remove this value, method = validate_fillna_kwargs(value, method) mask = self.isna() if is_array_like(value): if len(value) != len(self): raise ValueError( f"Length of 'value' does not match. Got ({len(value)}) " f" expected {len(self)}") value = value[mask] if mask.any(): if method is not None: func = pad_1d if method == "pad" else backfill_1d new_values = func(self._ndarray, limit=limit, mask=mask) new_values = self._from_sequence(new_values, dtype=self.dtype) else: # fill with value new_values = self.copy() new_values[mask] = value else: new_values = self.copy() return new_values
def fillna(self, value=None, method=None, limit=None): from pandas.api.types import is_array_like from pandas.util._validators import validate_fillna_kwargs from pandas.core.missing import pad_1d, backfill_1d value, method = validate_fillna_kwargs(value, method) mask = self.isna() if is_array_like(value): if len(value) != len(self): raise ValueError("Length of 'value' does not match. Got ({}) " " expected {}".format(len(value), len(self))) value = value[mask] if mask.any(): if method is not None: func = pad_1d if method == "pad" else backfill_1d new_values = func(self.astype(object), limit=limit, mask=mask) new_values = self._from_sequence(new_values, self._dtype) else: # fill with value new_values = np.asarray(self) if isinstance(value, Geometry): value = [value] new_values[mask] = value new_values = self.__class__(new_values, dtype=self.dtype) else: new_values = self.copy() return new_values
def test_is_array_like(): assert inference.is_array_like(Series([])) assert inference.is_array_like(Series([1, 2])) assert inference.is_array_like(np.array(["a", "b"])) assert inference.is_array_like(Index(["2016-01-01"])) class DtypeList(list): dtype = "special" assert inference.is_array_like(DtypeList()) assert not inference.is_array_like([1, 2, 3]) assert not inference.is_array_like(tuple()) assert not inference.is_array_like("foo") assert not inference.is_array_like(123)
def __init__(self, array, dtype=None, copy=None): # Choose default dtype for empty arrays try: if len(array) == 0 and dtype is None: dtype = 'float64' except: # len failed pass # See if we can determine arrow array type if isinstance(dtype, GeometryDtype): # Use arrow type as-is arrow_dtype = dtype.arrow_dtype elif isinstance(dtype, pa.DataType): arrow_dtype = dtype elif dtype is not None and dtype != np.dtype('object'): # Scalar element dtype arrow_dtype = self._arrow_type_from_numpy_element_dtype(dtype) else: # Let arrow infer type arrow_dtype = None # Unwrap GeometryList elements to numpy arrays if is_array_like(array) or isinstance(array, list): array = [_unwrap_geometry(el, self._element_type) for el in array] array = pa.array(array, type=arrow_dtype) elif isinstance(array, pa.Array): # Nothing to do pass elif isinstance(array, pa.ChunkedArray): array = pa.concat_arrays(array.chunks) else: raise ValueError("Unsupported type passed for {}: {}".format( self.__class__.__name__, type(array))) # Save off pyarrow array self.data = array # Compute types np_type = self._numpy_element_dtype_from_arrow_type(self.data.type) self._numpy_element_type = np.dtype(np_type) self._dtype = self._dtype_class(np_type) # Initialize backing property for spatial index self._sindex = None
def to_geometry_array(data, dtype=None): from . import (PointArray, MultiPointArray, LineArray, RingArray, MultiLineArray, PolygonArray, MultiPolygonArray) if sg is not None: shapely_to_spatialpandas = { sg.Point: PointArray, sg.MultiPoint: MultiPointArray, sg.LineString: LineArray, sg.LinearRing: RingArray, sg.MultiLineString: MultiLineArray, sg.Polygon: PolygonArray, sg.MultiPolygon: MultiPolygonArray, } else: shapely_to_spatialpandas = {} # Normalize dtype from string if dtype is not None: dtype = pd.array([], dtype=dtype).dtype err_msg = "Unable to convert data argument to a GeometryList array" if is_geometry_array(data): # Keep data as is pass elif (is_array_like(data) or isinstance(data, (list, tuple)) or gp and isinstance(data, (gp.GeoSeries, gp.array.GeometryArray))): if dtype is not None: data = dtype.construct_array_type()(data, dtype=dtype) elif len(data) == 0: raise ValueError( "Cannot infer spatialpandas geometry type from empty collection " "without dtype.\n") else: # Check for list/array of geometry scalars. first_valid = None for val in data: if val is not None: first_valid = val break if isinstance(first_valid, Geometry): # Pass data to constructor of appropriate geometry array data = first_valid.construct_array_type()(data) elif type(first_valid) in shapely_to_spatialpandas: if isinstance(first_valid, sg.LineString): # Handle mix of sg.LineString and sg.MultiLineString for val in data: if isinstance(val, sg.MultiLineString): first_valid = val break elif isinstance(first_valid, sg.Polygon): # Handle mix of sg.Polygon and sg.MultiPolygon for val in data: if isinstance(val, sg.MultiPolygon): first_valid = val break array_type = shapely_to_spatialpandas[type(first_valid)] data = array_type.from_geopandas(data) else: raise ValueError(err_msg) else: raise ValueError(err_msg) return data