Python Panda get value of cell with x y coordinates

Viewed 1138

I want to use Pandas to store values about my cars. I can view the information in a coordinate system like setup with the Pivot command, but only one kind of info per Pivot. I also want to be able to get the values fast, like with a class (cars.[x][y].x_goal). How do I do this? Or is there a better way to store coordinat system information like this? This is what I have tried. The print(result) at the end does not work.

import pandas as pd

cars = pd.DataFrame({'x': [1, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4],
                     'y': [1, 2, 3, 4, 1, 3, 1, 2, 3, 1, 2, 3],
                     'x_goal': [55, 5, 4, 10, 2, 2, 3, 31, 33, 41, 42, 34],
                     'y_goal': [3, 1, 10, 2, 12, 31, 3, 13, 4, 4, 4, 18]})

print('x_goal')
print(cars.pivot('x','y','x_goal').values)
     [[55.  5.  4. 10.]
      [ 2. nan  2. nan]
      [ 3. 31. 33. nan]
      [41. 42. 34. nan]]

print('y_goal')
print(cars.pivot('x','y','y_goal').values)
      [[ 3.  1. 10.  2.]
      [12. nan 31. nan]
      [ 3. 13.  4. nan]
      [ 4.  4. 18. nan]]


print('x_goal at 2,3')
df_filt = cars[cars['x'] == 2 & cars['y'] == 3]
result = df_filt.get_value(df_filt.index[0],'VALUE')
print(result)
2 Answers

You can get results directly from the data frame as follows:

result = cars[(cars['x']==2) & ((cars['y']==3))]['x_goal']
print(result)

Or better, as suggested by @S3DEV in the comments:

result = cars.loc[((cars['x']==2) & (cars['y']==3)), 'x_goal']

If you want to use a pivot:

pivot = cars.pivot_table(index='x', columns='y', values='x_goal')
result2 = pivot.loc[2,3]
print(result2)

You can also use a query:

result3 = cars.query('x == 2 & y == 3')['x_goal']
print(result3)

I would structure it using a dictionary rather than using pandas. My example allows you to lookup the x and y goal in constant time for any x y coordinate. You could easily construct the same dictionary from the pandas dataframe by iterating over it with iterrows or itertuples.

This won't work well using floats for coordinates - floats should generally not be used for dictionary keys because of errors introduced by limited floating point precision. You have int coordinates so all good.

You could also store x_goal and y_goal as 2D numpy arrays and access values like x_goal_np_array[x, y]. This would also be constant time. Your code already produces these arrays.

car_data = {
    'x': [1, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4],
    'y': [1, 2, 3, 4, 1, 3, 1, 2, 3, 1, 2, 3],
    'x_goal': [55, 5, 4, 10, 2, 2, 3, 31, 33, 41, 42, 34],
    'y_goal': [3, 1, 10, 2, 12, 31, 3, 13, 4, 4, 4, 18],
}

n_cars = len(car_data["x"])

# sanity check that all lists in car_data is same length:
assert all(len(v) == n_cars for v in car_data.values())

car_map = {}
for i in range(n_cars):
    x, y = car_data["x"][i], car_data["y"][i]
    x_goal, y_goal = car_data["x_goal"][i], car_data["y_goal"][i]
    car_map[(x, y)] = {"x_goal": x_goal, "y_goal": y_goal}

from pprint import pprint
pprint(car_map)
# Get x and y goal for car at (x, y) = (4, 1) in constant time.
print(car_map[(4, 1)]["x_goal"])
print(car_map[(4, 1)]["y_goal"])

output:

{(1, 1): {'x_goal': 55, 'y_goal': 3},
 (1, 2): {'x_goal': 5, 'y_goal': 1},
 (1, 3): {'x_goal': 4, 'y_goal': 10},
 (1, 4): {'x_goal': 10, 'y_goal': 2},
 (2, 1): {'x_goal': 2, 'y_goal': 12},
 (2, 3): {'x_goal': 2, 'y_goal': 31},
 (3, 1): {'x_goal': 3, 'y_goal': 3},
 (3, 2): {'x_goal': 31, 'y_goal': 13},
 (3, 3): {'x_goal': 33, 'y_goal': 4},
 (4, 1): {'x_goal': 41, 'y_goal': 4},
 (4, 2): {'x_goal': 42, 'y_goal': 4},
 (4, 3): {'x_goal': 34, 'y_goal': 18}}
41
4
Related