-
-
Notifications
You must be signed in to change notification settings - Fork 18.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
API: Validate keyword arguments to fillna #19684
Conversation
@@ -1607,6 +1607,9 @@ def fillna(self, value=None, method=None, limit=None): | |||
------- | |||
filled : Categorical with NA/NaN filled | |||
""" | |||
value, method = validate_fillna_kwargs( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note, I added this keyword since it's possible have a tuple / list for a category
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to add a test for this? (I mean filling a categorical with such categories, so the purpose of validate_scalar_dict_value=False
is exercised)
pandas/util/_validators.py
Outdated
if value is None and method is None: | ||
raise ValueError("Must specify a fill 'value' or 'method'.") | ||
elif value is None and method is not None: | ||
clean_fill_method(method) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
method = clean_fill_method(method) ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, thought about it. Meant to double check one thing in categorical but forgot. One sec...
Parameters | ||
---------- | ||
value, method : object | ||
The 'value' and 'method' keyword arguments for 'fillna'. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happened to validate_scalar_dict_value
in the docstring?
Codecov Report
@@ Coverage Diff @@
## master #19684 +/- ##
==========================================
+ Coverage 91.61% 91.61% +<.01%
==========================================
Files 150 150
Lines 48892 48900 +8
==========================================
+ Hits 44792 44800 +8
Misses 4100 4100
Continue to review full report at Codecov.
|
cat = Categorical([1, 2, 3]) | ||
|
||
xpr = "Cannot specify both 'value' and 'method'." | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you remove the line between the message and the condition, personal preference but its slightly distracting
Merging later today if no objections. |
let me look |
method = clean_fill_method(method) | ||
|
||
elif value is not None and method is None: | ||
if validate_scalar_dict_value and isinstance(value, (list, tuple)): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This check doesn't seem especially useful / correct given the error message.
There are many things that are not scalars or dicts, but also not lists
or tuples
, so we would fail to hit this TypeError.
But I was trying to keep this as a straight refactor for NDFrame.fillna, with the only behavior change being Categorical.fillna
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I dont' think this is odd to want to validate that a scalar can be only a certain type. maybe would change this
validate_scalar=lambda x: is_scalar(x) or is_dict_like(x)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this parameter name is terrible, ideally would like to change this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Two things:
- Please don't call a change by a contributor "terrible". It's not helpful.
- The error message says "'value' parameter must be a scalar or dict". That seems to match the parameter name pretty well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the parameter name is terrible, obviously NOT the contributor, which I didn't say or imply at all. It needs to be changed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The parameter name is certainly descriptive in what it does, and it is for an internal method, so it's not much of a problem it is that long. Why bother for the rest?
pandas/util/_validators.py
Outdated
value, method : object | ||
The 'value' and 'method' keyword arguments for 'fillna'. | ||
validate_scalar_dict_value : bool, default True | ||
Whether to validate that 'value' is a scalar or dict; specifically |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: replace the semicolon with a comma.
raise ValueError("Must specify a fill 'value' or 'method'.") | ||
elif value is None and method is not None: | ||
method = clean_fill_method(method) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
extra line here (make consistent across this function)
method = clean_fill_method(method) | ||
|
||
elif value is not None and method is None: | ||
if validate_scalar_dict_value and isinstance(value, (list, tuple)): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I dont' think this is odd to want to validate that a scalar can be only a certain type. maybe would change this
validate_scalar=lambda x: is_scalar(x) or is_dict_like(x)
I was trying to add a test for In [1]: import pandas as pd
In [2]: pd.Categorical([(1, 2), None]).fillna((1, 2))
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-2-73c5b4ab00c2> in <module>()
----> 1 pd.Categorical([(1, 2), None]).fillna((1, 2))
~/sandbox/pandas-ip/pandas/pandas/util/_decorators.py in wrapper(*args, **kwargs)
136 else:
137 kwargs[new_arg_name] = new_arg_value
--> 138 return func(*args, **kwargs)
139 return wrapper
140 return _deprecate_kwarg
~/sandbox/pandas-ip/pandas/pandas/core/arrays/categorical.py in fillna(self, value, method, limit)
1664 raise TypeError('"value" parameter must be a scalar, dict '
1665 'or Series, but you passed a '
-> 1666 '"{0}"'.format(type(value).__name__))
1667
1668 return self._constructor(values, categories=self.categories,
TypeError: "value" parameter must be a scalar, dict or Series, but you passed a "tuple" I've left the |
doc/source/whatsnew/v0.23.0.txt
Outdated
@@ -590,6 +590,8 @@ Other API Changes | |||
object frequency is ``None`` (:issue:`19147`) | |||
- Set operations (union, difference...) on :class:`IntervalIndex` with incompatible index types will now raise a ``TypeError`` rather than a ``ValueError`` (:issue:`19329`) | |||
- :class:`DateOffset` objects render more simply, e.g. "<DateOffset: days=1>" instead of "<DateOffset: kwds={'days': 1}>" (:issue:`19403`) | |||
- :func:`pandas.merge` provides a more informative error message when trying to merge on timezone-aware and timezone-naive columns (:issue:`15800`) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there is a datetimelike section for other api changes now
method = clean_fill_method(method) | ||
|
||
elif value is not None and method is None: | ||
if validate_scalar_dict_value and isinstance(value, (list, tuple)): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this parameter name is terrible, ideally would like to change this
thanks @TomAugspurger |
Closes #19682