-1

I would like to loop into a list of pandas dataframe variables, but with the possibility of choosing different index positions

raw_data = {'v1': [10,np.nan,50,30],'v2': [10,-10,50,-20],'v3':[120,-130,509,-230],'v4': [5,78,34,66]}

df = pd.DataFrame(raw_data, columns = ['v1','v2','v3','v4'])

columns = ['v1','v2','v3','v4']

#pseudo code: i+1 represents the following element in the list, after "i" element
for i in columns:
    print(df[i])
    print(df[i+1])

in real life I would like to do more complex operations to pairs of variables, like applying a function to v1 and v3, then v2 and v4, then v3 and v5, etc.

for instance: create a new var called 'new_varv1, which is the difference between v1 and v3. then the loop will do the same with v2 and v4, storing the result in new_varv2, etc

for i in columns:
    df['new_var'+i]=df[i]-df[i+2]
progster
  • 877
  • 3
  • 15
  • 27

2 Answers2

0

If I am understanding your question correctly, you could do something like this:

ctr = 1
for i in columns:
    print(df[i])
    print(df[columns[ctr]])
    ctr+=1
qbzenker
  • 4,412
  • 3
  • 16
  • 23
0

The most pythonic and recommended way is enumerate()

https://docs.python.org/2.3/whatsnew/section-enumerate.html

for (i, c) in enumerate(columns, start=1):
        print(df[c])
        print(df[columns[i-1]])

See Python - Previous and next values inside a loop

for more convoluted examples

Sometimes, if only previous/next element needed I use

prev = df[columns[0]]
if columns
    for i in columns[1:]:
        next = df[i] 
        print(next)
        print(prev)
        prev = next

Or just resort to classic loop

for i in range(len(columns)-1):
    print(df[columns[i]])
    print(df[columns[i+1]])

If you feel funky

for next, prev in zip(columns, columns[0:]):
    print(df[next])
    print(df[prev])

The index, provided in the enumerate solution is helpful to check that index value does not go beyond list boundaries.

If you strongly dislike using index variable, you might be able to use deque, which is list like and, probably try-except to silence boundary errors

from collections import deque
c = deque(columns)
for c0 in c[1:-3]:

    print(df[c0])
    print(df[c[-1]])

    print(df[c[3]])
    c.rotate(-1)
Community
  • 1
  • 1
Serge
  • 3,387
  • 3
  • 16
  • 34
  • the xrange does not print anything. I would need something like this: for (i, c) in enumerate(columns): print(df[c]),print(df[c[-1]]) – progster Apr 14 '17 at 14:04
  • you should use index in code and yet make sure index does not go beyond the array boundaries: by checking array boundaries, or (in your simple case) by adjusting the loop range. – Serge Apr 14 '17 at 15:02
  • An interesting question, can one make you code correct by tinkering with c type. Not sure is it possible, may be one have resort to OOP? One idea is tinker with dequeue `from collections import deque; past_n_future = deque(columns[:]); for c in columns: print(c); print past_n_future[-1]; print past_n_future[3]; past_n_future.rotate(-1)` – Serge Apr 14 '17 at 16:14