Home > front end >  Python: How to pass multiple x, y coordinates from a df into a function at once?
Python: How to pass multiple x, y coordinates from a df into a function at once?

Time:09-17

I have a df containing x, y coordinates that looks like this:

x    y
280  230
230  247
219  255
209  270
203  290
199  313
198  336
204  365
208  372
220  392
253  429
281  448
...  ...

The function that I created must take in 4 x coordinates and 4 corresponding y coordinates at a time, however I don't know how to iterate through a df and pass 4 rows of data at a time. Here is an example of my function call at the moment:

my_function(ax, ay, bx, by, cx, cy, dx, dy)

The function call doesn't have to be this way, I just need to be able to access all 4 x and y coordinates.

How would I go about passing the data into my function?

Thank you!

CodePudding user response:

Assuming you want to pass consecutive slices of rows to your function you can group every 4 rows and flatten the dataframe to get the shape you need.

def my_function(ax, ay, bx, by, cx, cy, dx, dy):
    return f'ax={ax}, ay={ay}, bx={bx}, by={by}, cx={cx}, cy={cy}, dx={dx}, dy={dy}'

df.groupby(df.index//4).apply(lambda x: my_function(*x.to_numpy().ravel()))

Output

0    ax=280, ay=230, bx=230, by=247, cx=219, cy=255...
1    ax=203, ay=290, bx=199, by=313, cx=198, cy=336...
2    ax=208, ay=372, bx=220, by=392, cx=253, cy=429...
dtype: object

Dataframe used in this example

import pandas as pd
import io

t = '''
x    y
280  230
230  247
219  255
209  270
203  290
199  313
198  336
204  365
208  372
220  392
253  429
281  448'''
df = pd.read_csv(io.StringIO(t), sep='\s ')
df

Output

      x    y
0   280  230
1   230  247
2   219  255
3   209  270
4   203  290
5   199  313
6   198  336
7   204  365
8   208  372
9   220  392
10  253  429
11  281  448

CodePudding user response:

If you're using Pandas, then you may utilize the pandas.DataFrame.items() method (or one of the alternatives shown in the docs).

If you want to go through multiple rows in each iteration, then one way to do it would be to iterate over a zip() that takes four instances of the same generator as its arguments, or even simpler, call the generator four times in each iteration with a proper while loop condition that checks for exhaustion.

CodePudding user response:

You can set a custom grouper using np.arange(len(df))//4 to make groups of 4.

to get the function output back in the dataframe:

df.groupby(np.arange(len(df))//4).apply(lambda g: g.values.flatten())

output:

0    [280, 230, 230, 247, 219, 255, 209, 270]
1    [203, 290, 199, 313, 198, 336, 204, 365]
2    [208, 372, 220, 392, 253, 429, 281, 448]
dtype: object

to apply a function per group and get the result outside of the dataframe:

for name, g in df.groupby(np.arange(len(df))//4):
    print(f'group: {name}')
    print(g.values.flatten()) # replace print here with your function

output:

group: 0
[280 230 230 247 219 255 209 270]
group: 1
[203 290 199 313 198 336 204 365]
group: 2
[208 372 220 392 253 429 281 448]
  • Related