-
-
Notifications
You must be signed in to change notification settings - Fork 11.9k
ENH: add multi-field assignment helpers in np.lib.recfunctions #11526
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
Merged
Merged
Changes from 1 commit
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev
Previous commit
MAINT: Add new recfunctions to numpy function API
- Loading branch information
commit 61371de744b363eacdb2ae277c33d365164380f3
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -888,6 +888,12 @@ def _get_fields_and_offsets(dt, offset=0): | |
| fields.extend(_get_fields_and_offsets(field[0], field[1] + offset)) | ||
| return fields | ||
|
|
||
|
|
||
| def _structured_to_unstructured_dispatcher(arr, dtype=None, copy=None, | ||
| casting=None): | ||
| return (arr,) | ||
|
|
||
| @array_function_dispatch(_structured_to_unstructured_dispatcher) | ||
| def structured_to_unstructured(arr, dtype=None, copy=False, casting='unsafe'): | ||
| """ | ||
| Converts and n-D structured array into an (n+1)-D unstructured array. | ||
|
|
@@ -968,6 +974,11 @@ def structured_to_unstructured(arr, dtype=None, copy=False, casting='unsafe'): | |
| # finally is it safe to view the packed fields as the unstructured type | ||
| return arr.view((out_dtype, sum(counts))) | ||
|
|
||
| def _unstructured_to_structured_dispatcher(arr, dtype=None, names=None, | ||
| align=None, copy=None, casting=None): | ||
| return (arr,) | ||
|
|
||
| @array_function_dispatch(_unstructured_to_structured_dispatcher) | ||
| def unstructured_to_structured(arr, dtype=None, names=None, align=False, | ||
| copy=False, casting='unsafe'): | ||
| """ | ||
|
|
@@ -1061,6 +1072,10 @@ def unstructured_to_structured(arr, dtype=None, names=None, align=False, | |
| # finally view as the final nested dtype and remove the last axis | ||
| return arr.view(out_dtype)[..., 0] | ||
|
|
||
| def _apply_along_fields_dispatcher(func, arr): | ||
| return (arr,) | ||
|
|
||
| @array_function_dispatch(_apply_along_fields_dispatcher) | ||
| def apply_along_fields(func, arr): | ||
| """ | ||
| Apply function 'func' as a reduction across fields of a structured array. | ||
|
|
@@ -1100,6 +1115,10 @@ def apply_along_fields(func, arr): | |
| # works and avoids axis requirement, but very, very slow: | ||
| #return np.apply_along_axis(func, -1, uarr) | ||
|
|
||
| def _assign_fields_by_name_dispatcher(dst, src, zero_unassigned=None): | ||
| return dst, src | ||
|
|
||
| @array_function_dispatch(_assign_fields_by_name_dispatcher) | ||
| def assign_fields_by_name(dst, src, zero_unassigned=True): | ||
| """ | ||
| Assigns values from one structured array to another by field name. | ||
|
|
@@ -1137,6 +1156,10 @@ def assign_fields_by_name(dst, src, zero_unassigned=True): | |
| assign_fields_by_name(dst[name], src[name], | ||
| zero_unassigned) | ||
|
|
||
| def _require_fields_dispatcher(array, required_dtype): | ||
| return (array,) | ||
|
|
||
| @array_function_dispatch(_require_fields_dispatcher) | ||
| def require_fields(array, required_dtype): | ||
|
Member
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. This name strikes me as a little odd, but I also can't think of a better one. It might be handy to use the word "require" in the description somewhere, to make the name easier to remember. |
||
| """ | ||
| Casts a structured array to a new dtype using assignment by field-name. | ||
|
|
||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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 think there are places we learnt that
unsafewas a bad default, but ended up stuck with it, leaving users surprised by the conversion.Should we apply that learning here, and pick a more conservative default?
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 may have missed that. Maybe in #8733? But that was about assignment using
unsafecasting, with no option to specify otherwise, unlike here where there is a keyword the user can specify.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, that issue was one of the ones I was thinking of - thanks for linking it, I was looking for that for unrelated reasons too!
Unsafe just feels like an... unsafe default to me. In my opinion, unsafe behavior should be something you ask for, not something you get by default. You're picking between:
f(...)vsf(..., casting='safe')f(..., casting='unsafe')vsf(...)I'd much rather see the word 'unsafe' to tell me I need to think more carefully about that line of code, rather than having to look for the absence of it.
I don't have a good memory of how the other casting modes behave. I'd be inclined to pick
same_kindto match the default value of the casting argument for forufuncsUh 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.
Here's an argument for
unsafe:First, it matches the default for the same keyword in
astype, and so its easier for the user to remember if they are used to usingastype.Second, it seems like most of the time the user wants
unsafe, because there are many common casts that are ruled out otherwise. For instance casts fromf8toi8are disallowed withsame_kind, but I expect this is a very common cast.Actually, for reasons I don't understand, ufuncs seem to allow casts from
f8toi8even though they supposedly usesame_kind:So ufuncs appear to use
unsafecasting despite the keyword default??