Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit bf2597f

Browse filesBrowse files
committed
BUG: automatically convert recarray dtype to np.record
1 parent a99c775 commit bf2597f
Copy full SHA for bf2597f

File tree

Expand file treeCollapse file tree

4 files changed

+33
-32
lines changed
Filter options
Expand file treeCollapse file tree

4 files changed

+33
-32
lines changed

‎numpy/core/records.py

Copy file name to clipboardExpand all lines: numpy/core/records.py
+10-4Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,11 @@ def __new__(subtype, shape, dtype=None, buf=None, offset=0, strides=None,
423423
strides=strides, order=order)
424424
return self
425425

426+
def __array_finalize__(self, obj):
427+
if type(obj) is not type(self) and issubclass(obj.dtype.type, nt.void):
428+
recordtype = sb.dtype((record, self.dtype))
429+
super(recarray, self).__setattr__('dtype', recordtype)
430+
426431
def __getattribute__(self, attr):
427432
# See if ndarray has this attr, and return it if so. (note that this
428433
# means a field with the same name as an ndarray attr cannot be
@@ -456,6 +461,11 @@ def __getattribute__(self, attr):
456461
# Undo any "setting" of the attribute and do a setfield
457462
# Thus, you can't create attributes on-the-fly that are field names.
458463
def __setattr__(self, attr, val):
464+
465+
# Automatically convert (void) dtypes to records.
466+
if attr == 'dtype' and issubclass(val.type, nt.void):
467+
val = sb.dtype((record, val))
468+
459469
newattr = attr not in self.__dict__
460470
try:
461471
ret = object.__setattr__(self, attr, val)
@@ -838,8 +848,6 @@ def array(obj, dtype=None, shape=None, offset=0, strides=None, formats=None,
838848
if copy:
839849
new = new.copy()
840850
res = new.view(recarray)
841-
if issubclass(res.dtype.type, nt.void):
842-
res.dtype = sb.dtype((record, res.dtype))
843851
return res
844852

845853
else:
@@ -850,6 +858,4 @@ def array(obj, dtype=None, shape=None, offset=0, strides=None, formats=None,
850858
if dtype is not None and (obj.dtype != dtype):
851859
obj = obj.view(dtype)
852860
res = obj.view(recarray)
853-
if issubclass(res.dtype.type, nt.void):
854-
res.dtype = sb.dtype((record, res.dtype))
855861
return res

‎numpy/core/tests/test_records.py

Copy file name to clipboardExpand all lines: numpy/core/tests/test_records.py
+11-1Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,13 +88,23 @@ def test_recarray_from_repr(self):
8888
assert_equal(recordarr, recordarr_r)
8989

9090
assert_equal(type(recarr_r), np.recarray)
91-
assert_equal(recarr_r.dtype.type, np.void)
91+
assert_equal(recarr_r.dtype.type, np.record)
9292
assert_equal(recarr, recarr_r)
9393

9494
assert_equal(type(recordview_r), np.ndarray)
9595
assert_equal(recordview.dtype.type, np.record)
9696
assert_equal(recordview, recordview_r)
9797

98+
def test_recarray_views(self):
99+
a = np.array([(1,'ABC'), (2, "DEF")],
100+
dtype=[('foo', int), ('bar', 'S4')])
101+
b = np.array([1,2,3,4,5], dtype=np.int64)
102+
103+
assert_equal(np.rec.array(a).dtype.type, np.record)
104+
assert_equal(type(np.rec.array(a)), np.recarray)
105+
assert_equal(np.rec.array(b).dtype.type, np.int64)
106+
assert_equal(type(np.rec.array(b)), np.recarray)
107+
98108
def test_recarray_from_names(self):
99109
ra = np.rec.array([
100110
(1, 'abc', 3.7000002861022949, 0),

‎numpy/doc/structured_arrays.py

Copy file name to clipboardExpand all lines: numpy/doc/structured_arrays.py
+7-27Lines changed: 7 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,13 @@
258258
>>> recordarr = arr.view(dtype=dtype((np.record, arr.dtype)),
259259
... type=np.recarray)
260260
261+
For convenience, viewing an ndarray as type `np.recarray` will automatically
262+
convert to `np.record` datatype, so the dtype can be left out of the view: ::
263+
264+
>>> recordarr = arr.view(np.recarray)
265+
>>> recordarr.dtype
266+
dtype((numpy.record, [('foo', '<i4'), ('bar', '<f4'), ('baz', 'S10')]))
267+
261268
Record array fields accessed by index or by attribute are returned as a record
262269
array if the field has a structured type but as a plain ndarray otherwise. ::
263270
@@ -272,33 +279,6 @@
272279
attribute takes precedence. Such fields will be inaccessible by attribute but
273280
may still be accessed by index.
274281
275-
Partial Attribute Access
276-
------------------------
277-
278-
The differences between record arrays and plain structured arrays induce a
279-
small performance penalty. It is possible to apply one or the other view
280-
independently if desired. To allow field access by attribute only on the array
281-
object it is sufficient to view an array as a recarray: ::
282-
283-
>>> recarr = arr.view(np.recarray)
284-
285-
This type of view is commonly used, for example in np.npyio and
286-
np.recfunctions. Note that unlike full record arrays the individual elements of
287-
such a view do not have field attributes::
288-
289-
>>> recarr[0].foo
290-
AttributeError: 'numpy.void' object has no attribute 'foo'
291-
292-
To use the np.record dtype only, convert the dtype using the (base_class,
293-
dtype) form described in numpy.dtype. This type of view is rarely used. ::
294-
295-
>>> arr_records = arr.view(dtype((np.record, arr.dtype)))
296-
297-
In documentation, the term 'structured array' will refer to objects of type
298-
np.ndarray with structured dtype, 'record array' will refer to structured
299-
arrays subclassed as np.recarray and whose dtype is of type np.record, and
300-
'recarray' will refer to arrays subclassed as np.recarray but whose dtype is
301-
not of type np.record.
302282
303283
"""
304284
from __future__ import division, absolute_import, print_function

‎numpy/ma/core.py

Copy file name to clipboardExpand all lines: numpy/ma/core.py
+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3155,6 +3155,11 @@ def __setitem__(self, indx, value):
31553155
_mask[indx] = mindx
31563156
return
31573157

3158+
def __setattr__(self, attr, value):
3159+
super(MaskedArray, self).__setattr__(attr, value)
3160+
if attr == 'dtype':
3161+
mdtype = make_mask_descr(value)
3162+
self._mask = self._mask.view(mdtype, ndarray)
31583163

31593164
def __getslice__(self, i, j):
31603165
"""x.__getslice__(i, j) <==> x[i:j]

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.