Calculate a np.arange within a Panda dataframe from other columns

Viewed 251

I want to create a new column with all the coordinates the car needs to pass to a certain goal. This should be as a list in a panda.

To start with I have this:

import pandas as pd

cars = pd.DataFrame({'x_now':    np.repeat(1,5),
                     'y_now':    np.arange(5,0,-1),

                     'x_1_goal': np.repeat(1,5),
                     'y_1_goal': np.repeat(10,5)})

output would be:

     x_now  y_now  x_1_goal  y_1_goal
0      1      5         1        10
1      1      4         1        10
2      1      3         1        10
3      1      2         1        10
4      1      1         1        10

I have tried to add new columns like this, and it does not work

for xy_index in range(len(cars)):
    if cars.at[xy_index, 'x_now'] == cars.at[xy_index,'x_1_goal']:
        cars.at[xy_index, 'x_car_move_route'] = np.repeat(cars.at[xy_index, 'x_now'].astype(int),(
            abs(cars.at[xy_index, 'y_now'].astype(int)-cars.at[xy_index, 'y_1_goal'].astype(int))))
    else:
        cars.at[xy_index, 'x_car_move_route'] = \
            np.arange(cars.at[xy_index,'x_now'], cars.at[xy_index,'x_1_goal'],
                      (cars.at[xy_index,'x_1_goal'] - cars.at[xy_index,'x_now']) / (
                          abs(cars.at[xy_index,'x_1_goal'] - cars.at[xy_index,'x_now'])))
    

at the end I want the columns x_car_move_route and y_car_move_route so I can loop over the coordinates that they need to pass. I will show it with tkinter. I will also add more goals, since this is actually only the first turn that they need to make.

     x_now  y_now  x_1_goal  y_1_goal  x_car_move_route  y_car_move_route
0      1      5         1        10    [1,1,1,1,1]         [6,7,8,9,10]
1      1      4         1        10    [1,1,1,1,1,1]       [5,6,7,8,9,10] 
2      1      3         1        10    [1,1,1,1,1,1,1]     [4,5,6,7,8,9,10]
3      1      2         1        10    [1,1,1,1,1,1,1,1]   [3,4,5,6,7,8,9,10]
4      1      1         1        10    [1,1,1,1,1,1,1,1,1] [2,3,4,5,6,7,8,9,10]
1 Answers

You can apply() something like this route() function along axis=1, which means route() will receive rows from cars. It generates either x or y coordinates depending on what's passed into var (from args).

You can tweak/fix as needed, but it should get you started:

def route(row, var):
    var2 = 'y' if var == 'x' else 'x'

    now, now2 = row[f'{var}_now'], row[f'{var2}_now']
    goal, goal2 = row[f'{var}_1_goal'], row[f'{var2}_1_goal']
    diff, diff2 = goal - now, goal2 - now2

    if diff == 0:
        result = np.array([now] * abs(diff2)).astype(int)
    else:
        result = 1 + np.arange(now, goal, diff / abs(diff)).astype(int)
    return result

cars['x_car_move_route'] = cars.apply(route, args=('x',), axis=1)
cars['y_car_move_route'] = cars.apply(route, args=('y',), axis=1)
   x_now  y_now  x_1_goal  y_1_goal     x_car_move_route      y_car_move_route
0      1      5         1        10          [1,1,1,1,1]          [6,7,8,9,10]
1      1      4         1        10        [1,1,1,1,1,1]        [5,6,7,8,9,10]
2      1      3         1        10      [1,1,1,1,1,1,1]      [4,5,6,7,8,9,10]
3      1      2         1        10    [1,1,1,1,1,1,1,1]    [3,4,5,6,7,8,9,10]
4      1      1         1        10  [1,1,1,1,1,1,1,1,1]  [2,3,4,5,6,7,8,9,10]
Related