Your iterator is not creating indices, but the actual elements in the array
Use with AIfor label in labels_class
In the above label is not an index, but the actual element you are trying to change
You can do something like this:
Use with AIfor i, label in enumerate(labels_class):
labels_class[i] = 1 if (label == classifier) else 0
Answer from sedavidw on Stack OverflowYour iterator is not creating indices, but the actual elements in the array
Use with AIfor label in labels_class
In the above label is not an index, but the actual element you are trying to change
You can do something like this:
Use with AIfor i, label in enumerate(labels_class):
labels_class[i] = 1 if (label == classifier) else 0
The syntax for modifying array values with nditer is demonstrated at
http://docs.scipy.org/doc/numpy/reference/arrays.nditer.html#modifying-array-values
Use with AIa = np.arange(6).reshape(2,3)
for x in np.nditer(a, op_flags=['readwrite']):
x[...] = 2 * x
'x should be indexed with the ellipsis' refers to the x[...].
Indexing with enumerate is perfectly fine as well. But this is the way to do it with nditer. See later sections in the nditer page about using flags=['f_index'].
When iterating over arrays you need to clearly understand the difference between variables which are indexes, scalars, or array elements which can be modified. x = 1 is not the same as A[i]= 1 or x[...]=1.
python - Iterate and modify array with NumPy - Stack Overflow
Iterate and replace values through a numpy array Python - Stack Overflow
python - How to iterate and modify over a numpy array? - Stack Overflow
python - How do I iterate through a numpy array and perform calculations? - Stack Overflow
As others have said, using vectorization is typically better/faster/nicer/...
But if you have good reasons to use iteration, you can of course do it.
I just copied this from the official documentation:
>>> a = np.arange(6).reshape(2,3)
>>> a
array([[0, 1, 2],
[3, 4, 5]])
>>> for x in np.nditer(a, op_flags=['readwrite']):
... x[...] = 2 * x
...
>>> a
array([[ 0, 2, 4],
[ 6, 8, 10]])
You may want to work on vectors and not loops?
In [144]: cakes = np.array([2, 3])
In [145]: cakes * 2 + 2
Out[145]: array([6, 8])
There is a numpy function for this, numpy.full or numpy.full_like:
>>> x = np.array(([1,2,2], [1,4,3]))
>>> np.full(x.shape, 10)
array([[10, 10, 10],
[10, 10, 10]])
# OR,
>>> np.full_like(x, 10)
array([[10, 10, 10],
[10, 10, 10]])
If you want to iterate you can either use itertools.product:
>>> from itertools import product
>>> def Iter_Replace(x):
indices = product(*map(range, x.shape))
for index in indices:
x[tuple(index)] = 10
return x
>>> x = np.array([[1,2,2], [1,4,3]])
>>> Iter_Replace(x)
array([[10, 10, 10],
[10, 10, 10]])
Or, use np.nditer
>>> x = np.array([[1,2,2], [1,4,3]])
>>> for index in np.ndindex(x.shape):
x[index] = 10
>>> x
array([[10, 10, 10],
[10, 10, 10]])
You have two errors. There are missing parenthesis in the first line of main:
x = np.array(([1,2,2], [1,4,3]))
And you must replace range(x) by range(len(x)) in the Iter_Replace function.
You cannot mutate the length of a numpy array, because numpy assigns the required memory for an array upon its creation.
With
array = np.delete(array, idx+1)
You are creating a new array on the right hand side of the = and reassign the name array.
The return value for enumerate(np.nditer(array)) has already been created at that point and won't recognize that the name array has been rebound.
In principle, you can iterate over a sequence and mutate its length at the same time (generally not a good idea). The object just needs to have methods that let you mutate its length (like lists, for example).
Consider:
>>> l = [5, 4, 3, 2, 1]
>>> for idx, ele in enumerate(l):
...: if ele == 3:
...: l.pop(idx) # mutates l
...: print(ele)
...:
5
4
3
1
>>> l
[5, 4, 2, 1]
Notice that
lis mutated.- The loop does not print
2because popping an element reduces the indexes of all the remaining elements by one. Nowl[2] == 2, but index2has already been visited by the iterator, so the next print-call printsl[3]which is 1.
This proves that mutations to l have effect on subsequent iterations.
Instead of looping over an array, you can use where method to find indices of elements meeting some condition.
Then to delete the selected element (or elements), you can use delete method, passing the source array, and a list of indices. Then save the result, e.g. under the same variable.
To add an element, you can use append or insert methods (for details see Numpy documentation).
I have also found a SO post concerning how to loop and delete over an array. See Deleting elements from numpy array with iteration
There are several issues with your example (some of which may be actual problems, others just typos or over simplifiactions):
import numpy as np # if you want to use for-loops don't use numpy
rays = np.array(... # closing parentheses instead of brackets
# unequal dimensions row of 5 and row of 6
for i in range(rays): # rays is not a number, did you mean len(rays[0])?
for w in range(i): # w is not used anywhere
estimate = rays[0][i]/(rays[0][i]+rays[1][i])
# estimate is overwritten at each iteration
The whole point of using numpy is to avoid "manually" iterating through array elements using for-loops. You should think of your result as an operation between matrices (or vectors):
For example (without for-loops):
import numpy as np
rays = np.array([[7.651e-03, 7.284e-03, 5.134e-03, 7.442e-03, 3.035e-03],
[2.373e-03, 6.877e-03, 4.809e-03, 2.870e-04, 3.175e-04]])
estimates = rays[0]/(rays[0]+rays[1])
print(estimates)
[0.76326816 0.51437045 0.51634316 0.96286712 0.90529456]
Note that I removed the last value from the second row because numpy requires fixed dimensions (i.e. it cannot have one row with 5 elements and another with 6)
Your nested loop for w in range(i), though you're not doing anything with w, suggests that you may be looking for the ratio between cumulative sums. If that is the case, use the cumsum function from numpy:
estimates = np.cumsum(rays[0])/np.cumsum(rays[0]+rays[1])
print(estimates)
[0.76326816 0.61753153 0.58805087 0.65726163 0.67565445]
rays = [
[7.651e-03, 7.284e-03, 5.134e-03, 7.442e-03, 3.035e-03],
[2.373e-03, 6.877e-03, 4.809e-03, 2.870e-04, 3.175e-04],
]
for i in range(min(len(rays[0]), len(rays[1]))):
estimate = rays[0][i] / (rays[0][i] + rays[1][i])
print(estimate)
This is not related with numpy matrix, but how python deal with your
i = i - y
i - y produces a new reference of an array. When you assigns it to name i, so i is not referred to the one it was before, but the newly created array.
The following code will meet your purpose
for idx, i in enumerate(m):
m[idx] = i - y
Update: I realize that the easiest thing is to do
m = m-y
This does directly what I expected!
After having used Matlab pretty extensively for the past few years, I'm used to a few practices that aren't considered great in Python. For instance, when I wanted to iterate through an array and evaluate each individual value in Matlab, I would iterate over the indices of the array rather than the values of the array as one would do in Python. In other words, I would do something like for i in range(len(array)): instead of for x in array:.
While I see the benefit in iterating through the values, I don't know how to easily evaluate and modify values in this manner. If anyone has any insight as to how to go about this, I'd certainly appreciate it.
Just to provide a little more information, this is the most obvious way for me to change a particular value based on some criteria:
import numpy as np
A = np.arange(5)
for i in range(len(A)):
if A[i] == 3:
A[i] = 14I'm looking for a better, more pythonic way to do this. Thanks!