@@ -6752,7 +6752,7 @@ def _pad_or_backfill(
67526752 @overload
67536753 def fillna (
67546754 self ,
6755- value : Hashable | Mapping | Series | DataFrame = ... ,
6755+ value : Hashable | Mapping | Series | DataFrame ,
67566756 * ,
67576757 axis : Axis | None = ...,
67586758 inplace : Literal [False ] = ...,
@@ -6762,7 +6762,7 @@ def fillna(
67626762 @overload
67636763 def fillna (
67646764 self ,
6765- value : Hashable | Mapping | Series | DataFrame = ... ,
6765+ value : Hashable | Mapping | Series | DataFrame ,
67666766 * ,
67676767 axis : Axis | None = ...,
67686768 inplace : Literal [True ],
@@ -6772,7 +6772,7 @@ def fillna(
67726772 @overload
67736773 def fillna (
67746774 self ,
6775- value : Hashable | Mapping | Series | DataFrame = ... ,
6775+ value : Hashable | Mapping | Series | DataFrame ,
67766776 * ,
67776777 axis : Axis | None = ...,
67786778 inplace : bool = ...,
@@ -6786,7 +6786,7 @@ def fillna(
67866786 )
67876787 def fillna (
67886788 self ,
6789- value : Hashable | Mapping | Series | DataFrame | None = None ,
6789+ value : Hashable | Mapping | Series | DataFrame ,
67906790 * ,
67916791 axis : Axis | None = None ,
67926792 inplace : bool = False ,
@@ -6827,6 +6827,12 @@ def fillna(
68276827 reindex : Conform object to new index.
68286828 asfreq : Convert TimeSeries to specified frequency.
68296829
6830+ Notes
6831+ -----
6832+ For non-object dtype, ``value=None`` will use the NA value of the dtype.
6833+ See more details in the :ref:`Filling missing data<missing_data.fillna>`
6834+ section.
6835+
68306836 Examples
68316837 --------
68326838 >>> df = pd.DataFrame(
@@ -6909,101 +6915,92 @@ def fillna(
69096915 axis = 0
69106916 axis = self ._get_axis_number (axis )
69116917
6912- if value is None :
6913- raise ValueError ("Must specify a fill 'value'." )
6914- else :
6915- if self .ndim == 1 :
6916- if isinstance (value , (dict , ABCSeries )):
6917- if not len (value ):
6918- # test_fillna_nonscalar
6919- if inplace :
6920- return None
6921- return self .copy (deep = False )
6922- from pandas import Series
6923-
6924- value = Series (value )
6925- value = value .reindex (self .index )
6926- value = value ._values
6927- elif not is_list_like (value ):
6928- pass
6929- else :
6930- raise TypeError (
6931- '"value" parameter must be a scalar, dict '
6932- "or Series, but you passed a "
6933- f'"{ type (value ).__name__ } "'
6934- )
6918+ if self .ndim == 1 :
6919+ if isinstance (value , (dict , ABCSeries )):
6920+ if not len (value ):
6921+ # test_fillna_nonscalar
6922+ if inplace :
6923+ return None
6924+ return self .copy (deep = False )
6925+ from pandas import Series
6926+
6927+ value = Series (value )
6928+ value = value .reindex (self .index )
6929+ value = value ._values
6930+ elif not is_list_like (value ):
6931+ pass
6932+ else :
6933+ raise TypeError (
6934+ '"value" parameter must be a scalar, dict '
6935+ "or Series, but you passed a "
6936+ f'"{ type (value ).__name__ } "'
6937+ )
69356938
6936- new_data = self ._mgr .fillna (value = value , limit = limit , inplace = inplace )
6939+ new_data = self ._mgr .fillna (value = value , limit = limit , inplace = inplace )
69376940
6938- elif isinstance (value , (dict , ABCSeries )):
6939- if axis == 1 :
6940- raise NotImplementedError (
6941- "Currently only can fill "
6942- "with dict/Series column "
6943- "by column"
6944- )
6945- result = self if inplace else self .copy (deep = False )
6946- for k , v in value .items ():
6947- if k not in result :
6948- continue
6941+ elif isinstance (value , (dict , ABCSeries )):
6942+ if axis == 1 :
6943+ raise NotImplementedError (
6944+ "Currently only can fill with dict/Series column by column"
6945+ )
6946+ result = self if inplace else self .copy (deep = False )
6947+ for k , v in value .items ():
6948+ if k not in result :
6949+ continue
69496950
6950- res_k = result [k ].fillna (v , limit = limit )
6951+ res_k = result [k ].fillna (v , limit = limit )
69516952
6952- if not inplace :
6953- result [k ] = res_k
6953+ if not inplace :
6954+ result [k ] = res_k
6955+ else :
6956+ # We can write into our existing column(s) iff dtype
6957+ # was preserved.
6958+ if isinstance (res_k , ABCSeries ):
6959+ # i.e. 'k' only shows up once in self.columns
6960+ if res_k .dtype == result [k ].dtype :
6961+ result .loc [:, k ] = res_k
6962+ else :
6963+ # Different dtype -> no way to do inplace.
6964+ result [k ] = res_k
69546965 else :
6955- # We can write into our existing column(s) iff dtype
6956- # was preserved.
6957- if isinstance (res_k , ABCSeries ):
6958- # i.e. 'k' only shows up once in self.columns
6959- if res_k .dtype == result [k ].dtype :
6960- result .loc [:, k ] = res_k
6966+ # see test_fillna_dict_inplace_nonunique_columns
6967+ locs = result .columns .get_loc (k )
6968+ if isinstance (locs , slice ):
6969+ locs = np .arange (self .shape [1 ])[locs ]
6970+ elif isinstance (locs , np .ndarray ) and locs .dtype .kind == "b" :
6971+ locs = locs .nonzero ()[0 ]
6972+ elif not (
6973+ isinstance (locs , np .ndarray ) and locs .dtype .kind == "i"
6974+ ):
6975+ # Should never be reached, but let's cover our bases
6976+ raise NotImplementedError (
6977+ "Unexpected get_loc result, please report a bug at "
6978+ "https://github.com/pandas-dev/pandas"
6979+ )
6980+
6981+ for i , loc in enumerate (locs ):
6982+ res_loc = res_k .iloc [:, i ]
6983+ target = self .iloc [:, loc ]
6984+
6985+ if res_loc .dtype == target .dtype :
6986+ result .iloc [:, loc ] = res_loc
69616987 else :
6962- # Different dtype -> no way to do inplace.
6963- result [k ] = res_k
6964- else :
6965- # see test_fillna_dict_inplace_nonunique_columns
6966- locs = result .columns .get_loc (k )
6967- if isinstance (locs , slice ):
6968- locs = np .arange (self .shape [1 ])[locs ]
6969- elif (
6970- isinstance (locs , np .ndarray ) and locs .dtype .kind == "b"
6971- ):
6972- locs = locs .nonzero ()[0 ]
6973- elif not (
6974- isinstance (locs , np .ndarray ) and locs .dtype .kind == "i"
6975- ):
6976- # Should never be reached, but let's cover our bases
6977- raise NotImplementedError (
6978- "Unexpected get_loc result, please report a bug at "
6979- "https://github.com/pandas-dev/pandas"
6980- )
6981-
6982- for i , loc in enumerate (locs ):
6983- res_loc = res_k .iloc [:, i ]
6984- target = self .iloc [:, loc ]
6985-
6986- if res_loc .dtype == target .dtype :
6987- result .iloc [:, loc ] = res_loc
6988- else :
6989- result .isetitem (loc , res_loc )
6990- if inplace :
6991- return self ._update_inplace (result )
6992- else :
6993- return result
6988+ result .isetitem (loc , res_loc )
6989+ if inplace :
6990+ return self ._update_inplace (result )
6991+ else :
6992+ return result
69946993
6995- elif not is_list_like (value ):
6996- if axis == 1 :
6997- result = self .T .fillna (value = value , limit = limit ).T
6998- new_data = result ._mgr
6999- else :
7000- new_data = self ._mgr .fillna (
7001- value = value , limit = limit , inplace = inplace
7002- )
7003- elif isinstance (value , ABCDataFrame ) and self .ndim == 2 :
7004- new_data = self .where (self .notna (), value )._mgr
6994+ elif not is_list_like (value ):
6995+ if axis == 1 :
6996+ result = self .T .fillna (value = value , limit = limit ).T
6997+ new_data = result ._mgr
70056998 else :
7006- raise ValueError (f"invalid fill value with a { type (value )} " )
6999+ new_data = self ._mgr .fillna (value = value , limit = limit , inplace = inplace )
7000+ elif isinstance (value , ABCDataFrame ) and self .ndim == 2 :
7001+ new_data = self .where (self .notna (), value )._mgr
7002+ else :
7003+ raise ValueError (f"invalid fill value with a { type (value )} " )
70077004
70087005 result = self ._constructor_from_mgr (new_data , axes = new_data .axes )
70097006 if inplace :
0 commit comments