I've checked some previous questions but can't quite seem to get an answer, though I wouldn't be surprised if this has been asked before. I would like to perform some calculations on elements of an array that I index using a for loop.
I have two arrays:
S = [[4.21287783e-03 7.83625813e-03 1.42038926e-02 ... 3.15416197e-03
1.37110355e-03 9.45473448e-04]
[1.94774282e-03 1.36746081e-03 1.23485391e-03 ... 6.21054272e-04
5.31808587e-04 1.78796272e-04]
[1.20601337e-03 2.81822793e-04 6.32125664e-04 ... 2.72966598e-04
3.88162201e-04 1.89432902e-04]
...
[7.39537451e-05 1.20665168e-04 1.54863119e-04 ... 3.05247233e-04
2.26473099e-04 1.56650857e-04]
[9.29507556e-05 6.45091024e-05 9.84829924e-05 ... 3.07827294e-04
2.33815251e-04 1.52187484e-04]
[4.66322444e-05 3.16681323e-05 7.08467828e-05 ... 1.44890351e-04
7.91870831e-05 5.80408583e-05]]
frames = [ 1 2 3 4 5 6 7 8 9 ]
I iterate through my frames array, but want to iteratively perform a calculation on a single value (indexed with i) from the S array:
for i in frames:
np.log(S[:,i])
But I get an out-of-bounds error, ('index 9 is out of bounds for axis 1 with size 9') because i indexes to the end of frames. I tried:
np.log(S[:,(i-1)])
which didn't work - either because my syntax is wrong or my logic is wrong.
I also tried:
for i in frames:
i=i-1
np.log(S[:,i])
And get the same out of bounds error.
EDIT: I am confident that I can call S in this manner because I do so elsewhere in the script (and can sub in any integer for i and the script runs). My logic about using i as an index is wrong.
4 Answers 4
With the two lists that you define (you write about arrays but a copy-n-paste of your code produces lists):
In [30]: S = [23, 23.3, 34.2, 235, 23.1, 32.1, 23, 75, 4]
...: frames = [1, 2, 3, 4, 5, 6, 7, 8, 9]
In [31]: for i in frames:
...: print(S[:,i])
...:
TypeError: list indices must be integers or slices, not tuple
You can't use [:,i] indexing with lists.
In [32]: for i in frames:
...: print(S[i])
..:
23.3
34.2
235
23.1
32.1
23
75
4
---------------------------------------------------------------------------
IndexError: list index out of range
With frames you miss the first element of S, and get an error with the last index. Python indexing starts with 0!
Even if I make a numpy array your indexing is wrong:
In [33]: arr = np.array(S)
In [34]: for i in frames:
...: print(arr[:,i])
...:
IndexError: too many indices for array
arr is 1d, shape (9,). You can't use [:,i]` with that.
Do you want to select a part of S (or arr), for example the first the 3 elements?
In [36]: arr[:3]
Out[36]: array([23. , 23.3, 34.2])
In [37]: np.log(arr[:3])
Out[37]: array([3.13549422, 3.14845336, 3.53222564])
[:3] indexes a slice (both for list and arrays)
If the array is 2d, then you can use the [:,i] notation:
In [38]: A = arr.reshape(3,3)
In [39]: A
Out[39]:
array([[ 23. , 23.3, 34.2],
[235. , 23.1, 32.1],
[ 23. , 75. , 4. ]])
In [40]: A[:,0] # first column
Out[40]: array([ 23., 235., 23.])
3 Comments
i is created within bounds. If S has shape (n,) (n elements), frame will be all or some subset of [0...8]. That's what range(n) or np.arange(n) does. In other words, frame is created with full knowledge of array it will index. If an element of frame is too large, you have to decide what that means - is it an error, do you clip it at the maximum allowed, or does it wrap around, or some other magic?You can remove "9" in frames array, and you will see the result as below:
23.3
34.2
235
23.1
32.1
23
75
4
So now you know the array index starts from 0, not from 1. if you want to fix that, you need to replace the frames array:
frames = [0, 1, 2, 3, 4, 5, 6, 7, 8]
Comments
You have an extra comma.
Try this:
for i in frames:
np.log(S[:i])
My test:
$ python3
Python 3.7.2+ (default, Feb 27 2019, 15:41:59)
[GCC 8.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> S = [23, 23.3, 34.2, 235, 23.1, 32.1, 23, 75, 4]
>>> frames = [1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> for i in frames:
... print(S[:i])
...
[23]
[23, 23.3]
[23, 23.3, 34.2]
[23, 23.3, 34.2, 235]
[23, 23.3, 34.2, 235, 23.1]
[23, 23.3, 34.2, 235, 23.1, 32.1]
[23, 23.3, 34.2, 235, 23.1, 32.1, 23]
[23, 23.3, 34.2, 235, 23.1, 32.1, 23, 75]
[23, 23.3, 34.2, 235, 23.1, 32.1, 23, 75, 4]
>>>
Comments
Personally, I think you dont need to use frames to index S.
You can try this way:
for i in range(S.shape[0])
np.log(S[i])
4 Comments
S.shape is (9, ) , You use S[:,i] (2d index) to index 1d array. This is not right I think.S. For example, the first to third part of S is S[0:3], at least without dot",".