Python slicing behavior using for loop - python

I am trying to use a for loop to create a series from entries in a dataframe, however I am having difficulties getting the last element of the dataframe.
import pandas as pd
a = pd.DataFrame([0,1,2,3,4,5,6,7])
a.values[-1] # returns 7
a.values[-5:-1]# returns 3,4,5,6
a.values[-5:]# returns 3,4,5,6,7
b = []
for i in range(0,len(a)):
b.append(a.values[-(i+1):-i])
I would like for 7 to be included in the list b. I realize that when i=0, a.values gives an empty array, however I'm not sure how to fix this as I can't iterate i to be blank as shown above.

Why not just manually convert negative indices to positive indices?
for i in range(0, len(a)):
b.append(a.values[(len(a) - (i+1) - 1):(len(a) - i)])
This works because python doesn't care if your upper limit in a slice is out-of-bounds, so long as the lower-limit is in bounds.
But if you're just trying to reverse the list (which it seems like you're trying to do), have you considered b = reversed(a)?

I would like for 7 to be included in the list b
import pandas as pd
a = pd.DataFrame([0,1,2,3,4,5,6,7])
b = []
for i in range(0, len(a)):
b.append(a.iloc[i])
OR, As a one-liner:
b = [a.iloc[i] for i in range(0, len(a))]

This will remove the blank and include 7 in the list:
for i in range(0,len(a)):
b.append(a.values[-i-1])

Related

How can I avoid index out of range error with enumerating, while comparing each element to its neighbour?

I have an array that I am looping over and I want to compare each element to the element next to it, and if it is larger say, then I want to do something with its index. It's clear to me that enumeration would help in this case; however I am running into an 'index out of range error':
array = [1,2,3,4]
for index,i in enumerate(array):
if array[index]>array[index+1]:
...
While I know there are other ways of doing this,
is there a way I can make the above work with enumerate? I tried to do enumerate(array)-1 ; knowing this would not work. But anything of this sort that would fix the indexing error? Thanks
I know we can easily do the above with simply using 'i' from the for loop, but just curious if I can manipulate enumeration here.
You can just shorten the range:
for i, val in enumerate(array[:-1]):
if val > array[i+1]:
# do stuff
If you don't need the index, you can use zip to the same effect:
for prev, crnt in zip(array, array[1:]):
if prev > crnt:
# do stuff not requiring index
The slicing requires O(n) extra space, if you don't want that, you can use your original approach without enumerate, but a simple range:
for i in range(len(array)-1):
if array[i] > array[i+1]:
# ...
Use zip and slice:
for i, j in zip(array, array[1:]):
print(f'i: {i} - j: {j}')
Output:
i: 1 - j: 2
i: 2 - j: 3
i: 3 - j: 4
Doing this way will set index at 0 and i at 1. A list is starting at 0 in Python. So at i=3, you are looking at array[i+1]=array[4] which does not exist ! That is why the program is saying 'index out of range error'.
Here is what I suggest if you want to stick with lists:
array = [1,2,3,4]
for i in range(len(array)-1):
if array[i]>array[i+1]:
...
If you want to manipulate the index, then it will be the current index in your loop (i). Maybe I have not understood your issue correctly but I suggest you to use numpy if you want to work with array-like objects.
Charles
What logic do you need to apply for the last element in the list?
You can use the range function instead of enumerate.
If you don't need to implement business logic to last element, then use below:
array = [1,2,3,4]
l = len(array)
for i in range(l-1):
if array[i]>array[i+1]:
...
If you do need to implement business logic to last element then use below:
array = [1,2,3,4]
l = len(array)
for i in range(l):
if i==l-1:
implemet last elemt logic
else:
if array[i]>array[i+1]:
....

Using a for loop to sum every element in a numpy array

I am trying to make the transition from excel to python, but run in some troubles, with summing every element within an one dimensional array.
In excel this can be easily done, as in the attached image.
From excel I can clearly see the mathematical pattern for achieving this. My approach was to create a for loop, by indexing the array A.
This is my code:
import numpy as np
A = np.array([0.520094,0.850895E-1,-0.108374e1])
B = np.array([0]) #initialize array
B[0] = A[0]
A is equivalent to column A in excel & similarly B
Using a for loop to sum every element/row:
for i in range(len(A)):
i = i+1
B.append([B[i-1]+A[i]])
print(B)
This strategy doesn't work and keep getting erros. Any suggestion as to how I could make this work or is there a more elegant way of doing this?
Just use np.cumsum:
import numpy as np
A = np.array([0.520094,0.850895E-1,-0.108374e1])
cumsum = np.cumsum(A)
print(cumsum)
Output:
[ 0.520094 0.6051835 -0.4785565]
A manual approach would look like this:
A = np.array([0.520094,0.850895E-1,-0.108374e1])
B = [] # Create B as a list and not a numpy array, because it's faster to append
for i in range(len(A)):
cumulated = A[i]
if i > 0:
cumulated += B[i-1]
B.append(cumulated)
B = np.array(B) # Convert B from list to a numpy array

How to modify list of list elements python

I have a list of lists
check = [['KH8X070.jpeg', 'ZDO9A8O.jpeg', 'ZW25RD8.jpeg', '6ZLXW92.jpeg', 'HVLA5UT.jpeg', 'A4UDC12.jpeg', '2X5KO9A.jpeg', '5HZR4VV.jpeg', '24FWS4S.jpeg'], ['Z2QC6PW.jpeg', 'EHMK14E.jpeg', 'RTV0PRH.jpeg', '71S643D.jpeg', 'KECHDQ9.jpeg', 'RU6PYPB.jpeg'], ['UG9Z4SQ.jpeg', 'H0Y3SYV.jpeg', '61HCFOK.jpeg', '14KE527.jpeg', 'XMSM050.jpeg', '5KFI2V3.jpeg', 'QSJMKUB.jpeg', 'S6TX0ZM.jpeg', '8JV3K1Y.jpeg', 'XI9OOI7.jpeg', 'JMWDOPM.jpeg'], ['0SAXG3I.jpeg', 'LA5HJNO.jpeg', 'PHHAUSA.jpeg', '900Z7S7.jpeg']]
such that I have:
check = [[0,0,0,0,0,0,0,0,0],[1,1,1,1,1,1], [2,2,2,2,2,2,2,2,2,2,2], [3,3,3,3]]
I want to modify it such that in index list 0 of the list of list, I'll have 0's all through, in index 1 I would have 1's all through, in index 2 I'll have 2's all through and so on like that.
for i, j in enumerate(check):
checks = [...]
I know it should be a list comprehension there, but don't just know how to go about it. That's why I have come here for help.
Here's my take with an one-liner code :
>>> [map(lambda val : i, arr) for i,arr in enumerate(check)]
The above won't quite give you the result you need. But what you can do is
arr = []
for i, j in enumerate(check):
length = j
arr.append([i]*length)
This should work perfectly, I tried it out and it worked fine. Let me know how it works for you.

Append result of iteration in python

I am pretty new to python, i am using python 3 and have some difficulties to append the result of the iteration to the array, following is my chunk of my code:
A = np.random.randn(len(meas),numx)
lengthA = np.linspace(0,len(A[0])-1,num=len(A[0]),dtype=int)
anorm = []
for j in range(0,len(lengthA)):
x_normed = A/A.max(axis=0)
anorm[:,j] = A[:,j]*x_normed[j]
Is it necessary to append the new result to empty anom ? somehow the code always tell me that the list of the indices must be integer and not tuple. Any help will be appreciated.
When assigning a value to an array at index n via the array[index] = value syntax, the argument within the square brackets must be an integer. In your situation, j is an integer but [:,j] attempts to reference multiple indices within the array.
for j in range(0,len(lengthA)):
x_normed = A/A.max(axis=0)
anorm[j] = A[:,j]*x_normed[j]
As an aside, if you want your for loop to run for as many iterations as there are elements within lengthA, then you can simply do:
for j in lengthA:
do stuff

How to calculate numbers in a list [duplicate]

This question already has answers here:
Python: Finding differences between elements of a list
(12 answers)
Difference between consecutive elements in list [duplicate]
(3 answers)
Closed 4 years ago.
here is my code.
A = [86.14803712, 85.25496701, 86.50334271, 86.0266668, 86.61455594, 86.90445213, 86.65519315, 87.10116762, 87.08173861]
B = []
i = 0
for i in range(len(A)):
c = A[i]-A[i-1]
B.append(c)
print(c)
I want to get the differences between two continuous numbers in this list, eg,(85.25496701-86.14803712). So in the results, I should have eight numbers as results.
But the results I get are:
-0.9337014900000042
-0.8930701099999965
1.2483756999999969
-0.4766759099999973
0.5878891400000015
0.2898961899999932
-0.24925897999999336
0.4459744699999959
-0.019429009999996083
I don't need -0.9337014900000042 since it comes from the first number subtract the last number in the list. What should I do the fix it? Thanks
That's the strength and the weakness of python: index -1 is always valid when the list isn't empty, which can lead to programs not crashing but not doing what you want.
For those operations, it's better to use zip to interleave the list with a sliced version of itself without the first number:
A = [86.14803712, 85.25496701, 86.50334271, 86.0266668, 86.61455594, 86.90445213, 86.65519315, 87.10116762, 87.08173861]
diffs = [ac-ap for ac,ap in zip(A[1:],A)]
or with itertools.islice to avoid creating a new list to iterate on it:
import itertools
diffs = [ac-ap for ac,ap in zip(itertools.islice(A,1,None),A)]
result (8 values):
[-0.8930701099999965, 1.2483756999999969, -0.4766759099999973, 0.5878891400000015, 0.2898961899999932, -0.24925897999999336, 0.4459744699999959, -0.019429009999996083]
It's possible to do this in base Python, but you might like the semantic clarity of Pandas:
import pandas as pd
pd.Series(A).diff().values[1:]
array([-0.89307011, 1.2483757 , -0.47667591, 0.58788914, 0.28989619,
-0.24925898, 0.44597447, -0.01942901])
You can just do:
B = [x-y for x, y in zip(A[1:], A)]
print(B) # -> [-0.8930701099999965, 1.2483756999999969, -0.4766759099999973, 0.5878891400000015, 0.2898961899999932, -0.24925897999999336, 0.4459744699999959, -0.019429009999996083]
You need to make sure you star from a correct index. In your current code, in the first iteration of the loop you will be computing A[0] - A[-1]. Hence, you need to start i from 1 to ensure in the first iteration you compute the value of A[1] - A[0]. The corrected version of your code is here:
A = [86.14803712, 85.25496701, 86.50334271, 86.0266668, 86.61455594, 86.90445213, 86.65519315, 87.10116762, 87.08173861]
B = []
i = 0
for i in range(1, len(A)):
c = A[i]-A[i-1]
B.append(c)
print(c)
I think the problem is that the loop subtracts the first element to the last because the loop starts at index 0 and subtracts it from index -1 (python takes -1 as the last index of a list). A better solution imo would be:
A = [86.14803712, 85.25496701, 86.50334271, 86.0266668, 86.61455594,
86.90445213, 86.65519315, 87.10116762, 87.08173861]
B = []
i = 0
for i in range(len(A)-1):
c = -(A[i]-A[i+1])
B.append(c)
print(c)
The easiest would be:
result = [x-y for x,y in zip(A[1:], A[:-1])]

Categories

Resources