user8330379
user8330379

Reputation:

Error while creating numpy array

len = 5
results = np.empty(len)
for i in range(len):
    results[i] = ([999, 'sss'])

I would like to predefine the length of a list, which is 5 and then fill in some values which contains both numerical and string variables... However, whatever I use

for i in range(len):
    results[i] = ([[999], ['sss']])

or

for i in range(len):
    results[i] = [[999], ['sss']]

I got error message as

ValueError                                Traceback (most recent call last)
<ipython-input-114-4cfd5264742d> in <module>()
      2 results = np.empty(len)
      3 for i in range(len):
----> 4     results[i] = ([999, 'sss'])

ValueError: setting an array element with a sequence.

How should i do?

Upvotes: 0

Views: 164

Answers (2)

hpaulj
hpaulj

Reputation: 231385

Unless you really have a need for a numpy array with mixed dtype, I'd recommend making a list of lists:

In [96]: alist = []
In [97]: for i in range(5):
    ...:     alist.append([999, 'sss'])
    ...:     
In [98]: alist
Out[98]: [[999, 'sss'], [999, 'sss'], [999, 'sss'], [999, 'sss'], [999, 'sss']]

Or if you make a list of tuples, you can go on an make a structured array - 1d with 2 fields of the desired dtype:

In [99]: alist = []
In [100]: for i in range(5):
     ...:     alist.append((999, 'sss'))
     ...:     
     ...:     
In [101]: alist
Out[101]: [(999, 'sss'), (999, 'sss'), (999, 'sss'), (999, 'sss'), (999, 'sss')]
In [102]: np.array(alist, dtype='int,U3')
Out[102]: 
array([(999, 'sss'), (999, 'sss'), (999, 'sss'), (999, 'sss'),
       (999, 'sss')], dtype=[('f0', '<i8'), ('f1', '<U3')])

When trying to mix integers and strings you need to pay attention to the intended use.


Note what happens when you create an 'empty' array:

In [103]: arr = np.empty(4)
In [104]: arr
Out[104]: array([0.e+000, 0.e+000, 0.e+000, 5.e-324])
In [105]: arr.dtype
Out[105]: dtype('float64')

It creates an array of the desired size, but with a default dtype, float. The initial values are garbage - though displayed as floats.

That means that the only thing you can put in arr[0] is a float.

In [106]: arr[0]=999       # converted to float
In [107]: arr[1]='sss'
...
ValueError: could not convert string to float: 'sss'
In [108]: arr
Out[108]: array([9.99e+002, 0.00e+000, 0.00e+000, 4.94e-324])

And it won't accept a list or tuple either, a sequence. It has to be something that can be converted to a float.

Specifying an object dtype does let you put anything in elements, because the elements actually hold pointers - just like a list.

In [110]: arr = np.empty(4,dtype=object)
In [111]: arr
Out[111]: array([None, None, None, None], dtype=object)
In [112]: arr[0]=1
In [113]: arr[1]=.999
In [114]: arr[2]='sss'
In [115]: arr[3]=[999,'sss']
In [116]: arr
Out[116]: array([1, 0.999, 'sss', list([999, 'sss'])], dtype=object)

Such an array is either a glorified list, or a debased one, depending on your needs.

Upvotes: 1

sacuL
sacuL

Reputation: 51335

you could use the dtype 'object' for your results array:

length = 5
results = np.empty(length, dtype='object')
for i in range(length):
    results[i] = ([999, 'sss'])

>>> results
array([list([999, 'sss']), list([999, 'sss']), list([999, 'sss']),
       list([999, 'sss']), list([999, 'sss'])], dtype=object)

If what you're putting into your results array is always of length 2, better to specify the appropriate shape when you make your np.empty:

length = 5
results = np.empty((length,2), dtype='object')
for i in range(length):
    results[i] = ([999, 'sss'])

>>> results
array([[999, 'sss'],
       [999, 'sss'],
       [999, 'sss'],
       [999, 'sss'],
       [999, 'sss']], dtype=object)

Note, try not to use len as a variable, as it is already a built-in function in python (I replaced it with length in my examples above)

Upvotes: 2

Related Questions