37

Why do I get this error message? ValueError: setting an array element with a sequence. Thank you

Z=np.array([1.0,1.0,1.0,1.0])  

def func(TempLake,Z):
    A=TempLake
    B=Z
    return A*B

Nlayers=Z.size
N=3
TempLake=np.zeros((N+1,Nlayers))

kOUT=np.zeros(N+1)
for i in xrange(N):
    kOUT[i]=func(TempLake[i],Z)
DSM
  • 342,061
  • 65
  • 592
  • 494
user1419224
  • 1,285
  • 6
  • 14
  • 14
  • In case you get this error with _matplotlib_, maybe you did it like me and passed `labels=` something unexpected instead of a string or an array. – Nicolai Weitkemper Oct 28 '20 at 22:16

7 Answers7

57

You're getting the error message

ValueError: setting an array element with a sequence.

because you're trying to set an array element with a sequence. I'm not trying to be cute, there -- the error message is trying to tell you exactly what the problem is. Don't think of it as a cryptic error, it's simply a phrase. What line is giving the problem?

kOUT[i]=func(TempLake[i],Z)

This line tries to set the ith element of kOUT to whatever func(TempLAke[i], Z) returns. Looking at the i=0 case:

In [39]: kOUT[0]
Out[39]: 0.0

In [40]: func(TempLake[0], Z)
Out[40]: array([ 0.,  0.,  0.,  0.])

You're trying to load a 4-element array into kOUT[0] which only has a float. Hence, you're trying to set an array element (the left hand side, kOUT[i]) with a sequence (the right hand side, func(TempLake[i], Z)).

Probably func isn't doing what you want, but I'm not sure what you really wanted it to do (and don't forget you can usually use vectorized operations like A*B rather than looping in numpy.) That should explain the problem, anyway.

DSM
  • 342,061
  • 65
  • 592
  • 494
  • 86
    I found the message cryptic as well. – SherylHohman Mar 29 '17 at 00:39
  • 3
    There is discussion on numpy's github (https://github.com/numpy/numpy/issues/6584) about changing this message to better describe the various situations that create. Johnny Wong's answer below clarified what was happening in my case. – SherylHohman Mar 29 '17 at 00:45
  • 10
    I would like to have it telling me WHAT element is set by WHAT sequence. Not mentioning this is of no use. – Louis Apr 14 '17 at 08:58
  • @Louis: What would it possibly do? The code generating the exception message doesn't have access to the names `kOUT`, `i`, `func`, `TempLake`, etc, and those are in the traceback anyway. It just has an array, an index, and a sequence, and trying to include either the array or the sequence in the error message could take hundreds of lines of output for moderately-sized operands. – user2357112 Aug 09 '17 at 18:04
  • 3
    Yeah it's definitely a cryptic message. The Windows BSOD may even be more helpful than this. – Dave Voyles May 15 '18 at 13:03
  • @DSM I'm stuck with the same error I can't seem passed it, [any help will be much help](https://stackoverflow.com/questions/51978161/dataframe-valueerror-setting-an-array-element-with-a-sequence) – 3kstc Aug 23 '18 at 04:04
38

It's a pity that both of the answers analyze the problem but didn't give a direct answer. Let's see the code.

Z = np.array([1.0, 1.0, 1.0, 1.0])  

def func(TempLake, Z):
    A = TempLake
    B = Z
    return A * B
Nlayers = Z.size
N = 3
TempLake = np.zeros((N+1, Nlayers))
kOUT = np.zeros(N + 1)

for i in xrange(N):
    # store the i-th result of
    # function "func" in i-th item in kOUT
    kOUT[i] = func(TempLake[i], Z)

The error shows that you set the ith item of kOUT(dtype:int) into an array. Here every item in kOUT is an int, can't directly assign to another datatype. Hence you should declare the data type of kOUT when you create it. For example, like:

Change the statement below:

kOUT = np.zeros(N + 1)

into:

kOUT = np.zeros(N + 1, dtype=object)

or:

kOUT = np.zeros((N + 1, N + 1))

All code:

import numpy as np
Z = np.array([1.0, 1.0, 1.0, 1.0])

def func(TempLake, Z):
    A = TempLake
    B = Z
    return A * B

Nlayers = Z.size
N = 3
TempLake = np.zeros((N + 1, Nlayers))

kOUT = np.zeros(N + 1, dtype=object)
for i in xrange(N):
    kOUT[i] = func(TempLake[i], Z)

Hope it can help you.

Junning Huang
  • 492
  • 5
  • 8
  • But a single item in array of dtype=int can be assigned to `str` object for example... it just gives an error with list-like object. Shouldn't it raise and error with str too ? – S.B Jan 18 '21 at 19:40
  • Glad to know that my answer still being read. Yes, exactly. I set the return value of "func" to some strings, eg. "aaaa". It turns out that the same error occurs. – Junning Huang Jan 19 '21 at 20:46
5

I believe python arrays just admit values. So convert it to list:

kOUT = np.zeros(N+1)
kOUT = kOUT.tolist()
Luis Renato
  • 67
  • 1
  • 2
1
Z=np.array([1.0,1.0,1.0,1.0])  

def func(TempLake,Z):
    A=TempLake
    B=Z
    return A*B
Nlayers=Z.size
N=3
TempLake=np.zeros((N+1,Nlayers))
kOUT=np.vectorize(func)(TempLake,Z)

This works too , instead of looping , just vectorize however read below notes from the scipy documentation : https://docs.scipy.org/doc/numpy/reference/generated/numpy.vectorize.html

The vectorize function is provided primarily for convenience, not for performance. The implementation is essentially a for loop.

If otypes is not specified, then a call to the function with the first argument will be used to determine the number of outputs. The results of this call will be cached if cache is True to prevent calling the function twice. However, to implement the cache, the original function must be wrapped which will slow down subsequent calls, so only do this if your function is expensive.

Ahalya L
  • 17
  • 2
0

To put a sequence or another numpy array into a numpy array, Just change this line:

kOUT=np.zeros(N+1)

to:

kOUT=np.asarray([None]*(N+1))

Or:

kOUT=np.zeros((N+1), object)
Stephen Rauch
  • 47,830
  • 31
  • 106
  • 135
-1

KOUT[i] is a single element of a list. But you are assigning a list to this element. your func is generating a list.

-1

You can try the expand option in Series.str.split('seperator', expand=True).
By default expand is False.

expand : bool, default False
Expand the splitted strings into separate columns.

  • If True, return DataFrame/MultiIndex expanding dimensionality.
  • If False, return Series/Index, containing lists of strings.
barbsan
  • 3,418
  • 11
  • 21
  • 28
Kenny
  • 19
  • 2