简体   繁体   中英

Why don't zero-dimensional numpy arrays in records support item assignment?

First, a shape (4,) numpy array can be assigned:

In [33]: a = np.zeros((10,), dtype=[('k', '<u8'), ('t', '<f4'), ('d', np.bool, (4,))])

In [34]: b = np.ones((), dtype=np.bool)

In [35]: a[0][2][3] = b

But, a shape () cannot if it's in a record:

In [36]: a = np.zeros((10,), dtype=[('k', '<u8'), ('t', '<f4'), ('d', np.bool, ())])

In [37]: a[0][2][()] = b
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-37-075e4ba95b60> in <module>()
----> 1 a[0][2][()] = b

TypeError: 'numpy.bool_' object does not support item assignment

But if it's not in a record, it works just fine:

In [38]: a = np.zeros((), np.bool)

In [39]: a[()] = b

Why?


What a record type looks like:

In [4]: a
Out[4]:
array([(0,  0., [False, False, False, False]),
       (0,  0., [False, False, False, False]),
       (0,  0., [False, False, False, False]),
       (0,  0., [False, False, False, False]),
       (0,  0., [False, False, False, False]),
       (0,  0., [False, False, False, False]),
       (0,  0., [False, False, False, False]),
       (0,  0., [False, False, False, False]),
       (0,  0., [False, False, False, False]),
       (0,  0., [False, False, False, False])],
      dtype=[('k', '<u8'), ('t', '<f4'), ('d', '?', (4,))])

In [2]: a
Out[2]:
array([(0,  0., False), (0,  0., False), (0,  0., False), (0,  0., False),
       (0,  0., False), (0,  0., False), (0,  0., False), (0,  0., False),
       (0,  0., False), (0,  0., False)],
      dtype=[('k', '<u8'), ('t', '<f4'), ('d', '?')])

The first example:

a = np.zeros((10,), dtype=[('k', '<u8'), ('t', '<f4'), ('d', np.bool, (4,))])

Creates a 1-dimensional numpy array where each element contains Tuple(_, _, List[np.bool])

The index a[0] references:

(0,  0., [False, False, False, False])

Therefore a[0][2][3] references the np.bool inside ** below

(0,  0., [False, False, False, **False**])

and acts how you expected.

The second example:

a = np.zeros((10,), dtype=[('k', '<u8'), ('t', '<f4'), ('d', np.bool, ())])

Creates a 1-dimensional numpy array where each element contains Tuple(_, _, np.bool) eg

(0,  0., False)

So a[0][2] references:

(0, 0., **False**)

The third index a[0][2]**[()]** acts on the np.bool object, which is not indexable.

A simplified example that throws the same error is shown below:

a = [False]
a[0] = True    # works
a = True       # changed type from [bool] to bool
a[0] = True    # Fails b/c bools are not scriptable

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'bool' object does not support item assignment
array([(0,  0., False), (0,  0., False), (0,  0., False), (0,  0., False),
       (0,  0., False), (0,  0., False), (0,  0., False), (0,  0., False),
       (0,  0., False), (0,  0., False)],
      dtype=[('k', '<u8'), ('t', '<f4'), ('d', '?')])

Note that ('d', '?') is the same as though you had defined the field as ('d', np.bool) .

In my own example

In [621]: x = np.ones((3,),dtype=[('f0',int),('f1',int,()),('f2',int,(1,))])
In [622]: x
Out[622]: 
array([(1, 1, [1]), (1, 1, [1]), (1, 1, [1])],
      dtype=[('f0', '<i4'), ('f1', '<i4'), ('f2', '<i4', (1,))])

'f0' and 'f1' are indexed in the same way; they have the same description (except for name). np.dtype constructor has stripped off or ignored the () .

In [623]: x['f0']=np.arange(3)
In [624]: x['f1']=np.arange(3)
In [625]: x['f2']=np.arange(3)
....
ValueError: could not broadcast input array from shape (3) into shape (3,1)

So the problem, if there is one, isn't with indexing, but with dtype ignoring the () part of the descriptor.


In your first case, the 'd'` field can be accessed with the triple index, or with a 2d index:

In [649]: a['d'].shape
Out[649]: (10, 4)
In [650]: a[0]['d'][3]
....
In [651]: a['d'][0,3]

My x['f1'] field with '()' remains 1d

In [652]: x['f1'].shape
Out[652]: (3,)
In [653]: x['f2'].shape
Out[653]: (3, 1)

I can't think of a meaningful way of creating or indexing a 0d dimension. We don't want (3,0) shape, and can't have (3,()) shape or [:,()]` indexing.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM