Python Error: Setting an array element with a sequence - python

I am new to python, so please, bear with me!
This function:
def kerf(X,m):
[n_samples, ]= X.shape
n_sa, n_fe = m.shape
ker = np.zeros((n_samples, n_sa))
for i, x_i in enumerate(X):
for j, m_j in enumerate(m):
ker[i, j] = (np.dot(x_i, m_j)) # problem is here!!
return ker
I call it like this:
Z=kerf(myarray[0,[0,1]],myarray[:,[0,1]])
ker[i, j] = (np.dot(x_i, m_j))
ValueError: setting an array element with a sequence.
myarray is basically the same matrix. Why?

When I replace the problem line with:
print(np.dot(x_i, m_j).shape)
it repeatedly prints (2,).
ker[i, j] takes 1 value; 2 values is sequence.
Please give us the dimensions of the arrays at various points, such as myarray (I guessed and tried a (3,4)), and at the problem point. print(...shape) is an essential debugging tool in numpy.
Do you need help on figure out why it's (2,)? May I suggest stepping through the loop in an interactive shell, looking at shapes at various points along the way.
the 2 inputs to the dot look like:
(1.0, array([ 1., 1.]))
a scalar, and a 2 element array - so the dot is also a 2 element array.
You need to explain what size you expect these 2 arrays to be, and what size you expect the dot. Actually we can get the result - it's got to be (1,) or a scalar - 1 value to put in the one slot ker.
You can probably replace the double iteration with a single dot product (or if need be with an einsum call). But let's get this iteration working first.

Related

Trouble understanding the function of : in array indexing? Python

I have this line in the code:
next_J[v] = np.min(Q[v, :] + J)
Where essentially Q is an matrix of size n x n and J is a vector of size n. What does Q[v, :] mean?
I tried to code this out but still do not understand what exactly it does.
Q[v,:] is translated by the interpreter as Q.__getitem__((v, slice(None))
Note the (,) tuple syntax.
For a 2d array, this means select the v row. The slice selects all columns, and isn't actually needed in this context.
For a list this produces an error. alist[v] would work.
Q[v]+J may not work fot lists, depending on what J is. + is different for lists. The class of an object is important in understanding code.
The use of : in python indexing is basic. So is its use jn numpy indexing.
There's a lot more about using slicing with numpy arrays at https://numpy.org/doc/stable/user/basics.indexing.html#slicing-and-striding

ValueError: could not broadcast input array from shape (6) into shape (1)

I made a vector of constant values. The vector is (1 row, 6colums). Then, I call the vector in another function and I want to use each element of the vector for making other calcualtions. The problem is that I get the following error:
ValueError: could not broadcast input array from shape (6) into shape (1)
Why? Is there someone that can help me?
Best regards,
n=6
F = np.ones([1,n])
F = F*0.4
# F: [[0.4 0.4 0.4 0.4 0.4 0.4]]
# Other function
str=np.zeros([1,n])
for i in range(0, len(F)):
str[i] = 1000 * F[i]
# ValueError: could not broadcast input array from shape (6) into shape (1)
Your F is not a list of values, but a list of one list of values. I can see this by the extra [] surrounding your values. So when you do the calculation str[i] = 1000 * F[i] you are working with 2 lists. You could try replacing that line with str[0][i] = 1000 * F[0][i] to access the 0th element of the outerlist (which is just the list of values) and then picking the ith value from that list.
This might not be exactly the answer you are looking for, something that can help get good answers is to post the full traceback. Odds are you have much more to your error message than the one line ValueError, that extra information would be very useful posted in your questions! You could also add the definition for whatever Fd_ULS is.

How to convert row list to column list

How do you convert [1, 2, 3] to [[1],[2],[3]] in python?
Also, say I have a vector of length m with values ranging from 1 to 10, I want to create a matrix of size mx10 such that say if vector y = 1 then the matrix should be [0,1,0,0,0,0,0,0,0,0]. In octave it was possible with,
y_train = zeros(m,output_layer_size);
for i=1:output_layer_size
y_train(find(y==i),i)=1;
end
But similar function gives out VisibleDeprecationWarning warning in python and does give desired output
y_train = np.zeros((y.shape[0],10))
for i in range(10):
y_train[y==i][i]=1
Adding a dimenstion to a vector in numpy is easy. You have a number of options available, depending on what you want to do:
Use np.newaxis, which is often aliased by None, in your index:
v = v[:, None]
OR
v = [None, :]
Using newaxis allows you to control precisely whether the vector becomes a column or a row.
Reshape the vector:
v = v.reshape((1, -1))
OR
v = np.reshape(v, (-1, 1))
I have really shown four options here (np.reshape vs np.ndarray.reshape and row vs column). Using -1 in the new vector's dimensions means "whatever size is necessary to make it the same number of elements as the original". It is much easier than explicitly using the shape.
Use np.expand_dims, which is almost exactly equivalent to np.newaxis, but in functional form.
Construct a new array with ndmin=2:
v = np.array(v, copy=False, ndmin=2)
This method is the least flexible because it does not let you control the position of the new axis. It is usually used when the only thing that matters is the dimensionality and broadcasting takes care of the rest.
The second part of the question appears to be a simple use-case for fancy indexing in Python. Here is as IDEOne link where I unrolled your octave loop. You can rephrase it in Python as:
y_train = np.zeros((y.size, m_output));
y_train[np.arange(y.size), y] = 1
Here is an IDEOne link of the demo.
Transposing 1D array directly will not work. It will return the original array. Try this instead:
np.atleast_2d(x).T
The ones from the comment did not work for me but numpy.where() worked!
b=np.array([[0],[0],[2],[2],[4],[1],[6],[7],[5],[9]])
a=np.random.randint(10,size=(10,10))
for i in range(10):
c=np.zeros((1,10))
c[0][i]=1
a[np.where(b==i)[0]] = c
print a

Building a numpy matrix

I'm trying to build a matrix in numpy. The matrix dimensions should be (5001x7). Here is my code:
S=np.array([.0788,.0455,.0222,.0042,.0035,.0029,.0007])
#This is vector S, comprised of 7 scalars.
lamb=list(range(0,5001))
#This is a list of possible values for lambda, a parameter in my data.
M = np.empty([5001,7], order='C')
#This is the empty matrix which is to be filled in the iterations below.
for i in S:
for j in lamb:
np.append(M,((S[i]**2)/(lamb[j]+S[i]**2)))
The problem I'm having is that M remains a matrix of zero vectors.
Important details:
1) I've assigned the final line as:
M=np.append(M,((S[i]**2)/(lamb[j]+S[i]**2)))
I then get an array of values of length 70,014 in a 1d array. I'm not really sure what to make of it.
2) I've already tried switching the dtype parameter between 'float' and 'int' for matrix M.
3) I receive this warning when I run the code:
VisibleDeprecationWarning: using a non-integer number instead of an integer will result in an error in the future
app.launch_new_instance()
4) I'm working in Python 3.4
I really appreciate your help. Thank you!
1) append adds to the end of the array, which is why your final array has 5001x7x2=70014 elements. Only the first half is zeros. It flattens the array to 1D because you didn't specify an axis to append.
2) A much more "numpy" way to do this whole process is broadcasting
S=np.array([.0788,.0455,.0222,.0042,.0035,.0029,.0007])
lamb=np.arange(0,5001)
M=(S[:,None]**2)/(lamb[None,:]+S[:,None]**2)
np.append makes a copy of the array and appends values to the end of the copy (making the array larger each time), whereas I think you want to modify M in place:
for i in range(len(S)):
for j in range(len(lamb)):
M[j][i] = ((S[i]**2)/(lamb[j]+S[i]**2))

Numpy array, indexing and convolving confusion

I'm trying to complete the following function, but I have been running into problems with the indexing, resulting in "ValueError: operands could not be broadcast together with shapes (0,9) (5)".
I think my error might be coming from how I'm trying to call the values from ssd_difference[], but I'm not entirely sure.
Also how would I go about using convolve2d based on the hint given below? I understand numpy has a function for it, but I have no idea what I would need to put in to make it work.
Additional information: binomialFilter5() returns a 5x1 numpy array of dtype float representing a binomial filter. I'm also assuming that the "weights[]" are the ssd_difference[] values.
def transitionDifference(ssd_difference):
""" Compute the transition costs between frames, taking dynamics into
account.
Instructions:
1. Iterate through the rows and columns of ssd difference, ignoring the
first two values and the last two values.
1a. For each value at i, j, multiply the binomial filter of length
five (implemented later in the code) by the weights starting two
frames before until two frames after, and take the sum of those
products.
i.e. Your weights for frame i are:
[weight[i - 2, j - 2],
weight[i - 1, j - 1],
weight[i, j],
weight[i + 1, j + 1],
weight[i + 2, j + 2]]
Multiply that by the binomial filter weights at each i, j to get
your output.
It may take a little bit of understanding to get why we are
computing this, the simple explanation is that to change from
frame 4 to 5, lets call this ch(4, 5), and we make this weight:
ch(4, 5) = ch(2, 3) + ch(3, 4) + ch(4, 5) + ch(5, 6) + ch(6, 7)
This accounts for the weights in previous changes and future
changes when considering the current frame.
Of course, we weigh all these sums by the binomial filter, so
that the weight ch(4, 5) is still the most important one, but
hopefully that gives you a better understanding.
Args:
ssd_difference (numpy.ndarray): A difference matrix as produced by your
ssd function.
Returns:
output (numpy.ndarray): A difference matrix that takes preceding and
following frames into account. The output
difference matrix should have the same dtype as
the input, but be 4 rows and columns smaller,
corresponding to only the frames that have valid
dynamics.
Hint: There is an efficient way to do this with 2d convolution. Think about
the coordinates you are using as you consider the preceding and
following frame pairings.
"""
output = np.zeros((ssd_difference.shape[0] - 4,
ssd_difference.shape[1] - 4), dtype=ssd_difference.dtype)
# WRITE YOUR CODE HERE.
for i in range(len(ssd_difference)):
for j in range(len(ssd_difference)):
if i == 0:
if j > 1:
output[i,j] = np.sum( ssd_difference[i-2:i+2]*binomialFilter5())
elif i == ssd_difference.shape[0] - 1:
if j < ssd_difference.shape[1] - 2:
output[i,j] = np.sum( ssd_difference[i-2:i+2]*binomialFilter5())
else:
output[i,j] = np.sum( ssd_difference[i-2:i+2]*binomialFilter5())
# END OF FUNCTION.
return output
As I commented, you really should tell us the line that produced the error message.
But I can guess, since there are just a couple of lines that do an operation that involves broadcasting. Most likely it is:
output[i,j] = np.sum( ssd_difference[i-2:i+2]*binomialFilter5())
You write that binomialFilter5() produces a (5,1) array, but the error talks about a (5,). It probably doesn't matter here, but you really should keep the number of dimensions straight. Sometimes (5,1) is signficantly different from (5,).
output has shape (ssd_difference.shape[0] - 4, ssd_difference.shape[1] - 4). But you are iterating i,j both over range(len(ssd_difference)). output[i,j] will eventually result in an index error. Especially when iterating over a 2d array, it is better to use the correct shape element, rather than len().
But I suspect the immediate error results from ssd_difference[i-2:i+2]. When i==0, this is ssd_difference[-2:2]. This is producing the (0,9) array, since the -2 index means second from the last, which is larger than 2.
I think you are intending to pull 5 rows from this array, to match the 5 values in the other array. A correct iteration, would I think be:
for i in range(output.shape[0]):
for j in range(output.shape[1]):
....
output[i,j] = np.sum(ssd_difference[i:i+5, :] * binomialFilter5())
...
You should test expressions like that individually in an interactive shell, with selected values of i. ssd_difference[i:i+5, :] should have shape (5,9), and binomialFilter5() should be (5,1).

Categories

Resources