2

I'm using a method from somewhere else which needs the built-in type of integers int and not the type NumPy creates. Here is a simplification:

a = np.arange(6, dtype='int').reshape(2,3)
b = a.tolist()

f(a[0,0]) # fails
f(b[0][0]) # works

fail gives error message:

TypeError: bpy_struct: item.attr = val: expected sequence items of type int, not numpy.int64

Although tolist() works, I loose NumPy in the process. My question is, can I maintain the NumPy form and flexibility, with the built-in type of int?

6
  • Cast it to Python's integer object by using int(). Commented Aug 9, 2015 at 15:11
  • I want to maintain the array as a NumPy array, with a dtype of the built-in int type. int(a) fails. Commented Aug 9, 2015 at 15:15
  • 1
    I meant f(int(a[0,0])). Commented Aug 9, 2015 at 15:16
  • Please double check the part where I said "My question is..." Commented Aug 9, 2015 at 15:17
  • 1
    No, I don't think that is possible at the array level because Python's int is not a primitive data type and has no size limitation at all. Commented Aug 9, 2015 at 15:28

1 Answer 1

5

It may help to distinguish between what the array stores in its data buffer, and what it returns via indexing.

a=np.arange(6,dtype=int).reshape(2,3)

Its attributes, a.__array_interface__

{'strides': None,
 'descr': [('', '<i4')],
 'shape': (2, 3),
 'data': (171366744, False),
 'version': 3,
 'typestr': '<i4'}

The values are stored a 24 bytes (6 * 4), starting at the data memory location.

a[0,0] isn't just 4 bytes from the data buffer. It is really a single item 0d array. Technically its type is np.int32, but it has many of the same attributes and methods as an np.ndarray:

In [431]: a[0,0].__array_interface__
Out[431]: 
{'strides': None,
 'descr': [('', '<i4')],
 'shape': (),
 '__ref': array(0),
 'data': (171093512, False),
 'version': 3,
 'typestr': '<i4'}

.item() method can be used to pull that value out of the array object. In many cases an int32 can be used just like a Python primitive int, but evidently your function is picky, performing some sort of isinstance(i,int) test.

type(a[0,0])  # numpy.int32
type(a[0,0].item()) # int
type(int(a[0,0])  # int

a.tolist()[0][0] because that array method is designed to construct a nested list of Python primitives, stripped of all ndarray attributes. In effect it does .item() at the lowest level. Effectively it is:

In [444]: [[j.item() for j in i] for i in a]
Out[444]: [[0, 1, 2], [3, 4, 5]]
Sign up to request clarification or add additional context in comments.

4 Comments

Because a[0, 0] is 'array-like', one could of course apply tolist after the indexing: a[0, 0].tolist() will return an int. (Funnily enough, this means that tolist doesn't always return a list. Figure that.) Of course, a[0, 0].item() and int(a[0, 0]) are both much better at revealing the intention of what's going on.
OK this is new to me @das-g. And that's interesting (tolist applied to single NumPy element)!
While technically the answer to my question is "No, you can't" (comment by @AshwiniChaudhary) this answer gives a lot of helpful information to understand what is going on. Thanks!
Well, both built-in and Numpy float types actually give an array of scalars. I'd ask explicitly again the OP question: is there really no way to create an array of integers(not array-like)?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.