-
-
Notifications
You must be signed in to change notification settings - Fork 18.7k
API: Unify .update to generic #23192
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
Changes from all commits
0bb8325
56f569b
e1abe77
802f6ac
07784f0
f120d65
e500a22
d49b742
9183b50
411741a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,7 +21,7 @@ | |
ensure_float64) | ||
|
||
from pandas.core.dtypes.cast import infer_dtype_from_array | ||
from pandas.core.dtypes.missing import isna | ||
from pandas.core.dtypes.missing import isna, notna | ||
|
||
|
||
def mask_missing(arr, values_to_mask): | ||
|
@@ -75,6 +75,80 @@ def mask_missing(arr, values_to_mask): | |
return mask | ||
|
||
|
||
def update_array(this, that, overwrite=True, filter_func=None, | ||
errors='ignore'): | ||
""" | ||
Update one array with non-NA values from another array. | ||
Parameters | ||
---------- | ||
this : np.ndarray (one-dimensional) | ||
The array being updated. | ||
that : np.ndarray (one-dimensional) | ||
The array being used to update. | ||
overwrite : bool, default True | ||
How to handle non-NA values for overlapping keys: | ||
* True: overwrite original array's values with values from `that`. | ||
* False: only update values that are NA in `this`. | ||
filter_func : callable(1d-array) -> boolean 1d-array, optional | ||
Can choose to replace values other than NA. Return True for values | ||
that should be updated. | ||
errors : {'raise', 'ignore'}, default 'ignore' | ||
If 'raise', will raise a ValueError if `this` and `that` both contain | ||
non-NA data in the same place. | ||
Raises | ||
------ | ||
ValueError | ||
When `errors='raise'` and there's overlapping non-NA data. | ||
Returns | ||
------- | ||
updated : np.ndarray (one-dimensional) | ||
The updated array. | ||
See Also | ||
-------- | ||
Series.update : Similar method for `Series`. | ||
DataFrame.update : Similar method for `DataFrame`. | ||
dict.update : Similar method for `dict`. | ||
""" | ||
updated = _update_array(this, that, overwrite=overwrite, | ||
filter_func=filter_func, errors=errors) | ||
return this if updated is None else updated | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @jreback However, I was not comfortable with a public function having such unexpected behaviour, so I made the function I used originally private again (but still in |
||
|
||
|
||
def _update_array(this, that, overwrite=True, filter_func=None, | ||
errors='ignore'): | ||
""" | ||
Same as update_array, except we return None if `this` is not updated. | ||
""" | ||
import pandas.core.computation.expressions as expressions | ||
|
||
if filter_func is not None: | ||
with np.errstate(all='ignore'): | ||
mask = ~filter_func(this) | isna(that) | ||
else: | ||
if errors == 'raise': | ||
mask_this = notna(that) | ||
mask_that = notna(this) | ||
if any(mask_this & mask_that): | ||
raise ValueError("Data overlaps.") | ||
|
||
if overwrite: | ||
mask = isna(that) | ||
else: | ||
mask = notna(this) | ||
|
||
# don't overwrite columns unnecessarily | ||
if mask.all(): | ||
return None | ||
|
||
return expressions.where(mask, this, that) | ||
|
||
|
||
def clean_fill_method(method, allow_nearest=False): | ||
# asfreq is compat for resampling | ||
if method in [None, 'asfreq']: | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2385,14 +2385,59 @@ def combine_first(self, other): | |
|
||
return this.where(notna(this), other) | ||
|
||
def update(self, other): | ||
def update(self, other, join='left', overwrite=True, filter_func=None, | ||
errors='ignore'): | ||
""" | ||
Modify Series in place using non-NA values from passed | ||
Series. Aligns on index | ||
Modify Series in place using non-NA values from passed Series. | ||
Series will be aligned on indexes, and whenever possible, the dtype of | ||
the caller will be preserved. | ||
There is no return value. | ||
Parameters | ||
---------- | ||
other : Series | ||
other : Series, or object coercible into a Series | ||
Should have at least one matching index label with the calling | ||
Series. | ||
join : {'left'}, default 'left' | ||
Only left join is implemented, keeping the index and columns of the | ||
original object. | ||
.. versionadded:: 0.24.0 | ||
overwrite : bool, default True | ||
How to handle non-NA values for overlapping keys: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can you indicate with a versionadded tag what has changed compared to current |
||
* True: overwrite original DataFrame's values | ||
with values from `other`. | ||
* False: only update values that are NA in | ||
the original DataFrame. | ||
.. versionadded:: 0.24.0 | ||
filter_func : callable(1d-array) -> bool 1d-array, optional | ||
Can choose to replace values other than NA. Return True for values | ||
that should be updated. | ||
.. versionadded:: 0.24.0 | ||
errors : {'raise', 'ignore'}, default 'ignore' | ||
If 'raise', will raise a ValueError if the DataFrame and `other` | ||
both contain non-NA data in the same place. | ||
.. versionadded:: 0.24.0 | ||
Raises | ||
------ | ||
ValueError | ||
When `errors='ignore'` and there's overlapping non-NA data. | ||
Returns | ||
------- | ||
Nothing, the Series is modified inplace. | ||
See Also | ||
-------- | ||
DataFrame.update : Similar method for `DataFrame`. | ||
dict.update : Similar method for `dict`. | ||
Examples | ||
-------- | ||
|
@@ -2431,11 +2476,9 @@ def update(self, other): | |
2 6 | ||
dtype: int64 | ||
""" | ||
other = other.reindex_like(self) | ||
mask = notna(other) | ||
|
||
self._data = self._data.putmask(mask=mask, new=other, inplace=True) | ||
self._maybe_update_cacher() | ||
super(Series, self).update(other, join=join, overwrite=overwrite, | ||
filter_func=filter_func, | ||
errors=errors) | ||
|
||
# ---------------------------------------------------------------------- | ||
# Reindexing, sorting | ||
|
Uh oh!
There was an error while loading. Please reload this page.
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 isn't obvious from the diff (due to the code moving files), but now this keeps the dtype - yay!