Как определить 2D-массив координат (x, y)

У меня есть 2d-пространство координат (x, y), которое я хочу смоделировать в python, и хочу узнать, как определить 2d-пространство в python, где я могу присвоить несколько значений точке (x, y). Более поздние значения в координатах будут изменены на основе некоторых вычислений, зависящих от координат.

Я подумал об использовании массива numpy для создания массива 2d на основе размера, введенного пользователем. Я начал с создания массива нулей 2d n*m numpy, а более поздние части вычислений кода выполняются по точкам. Но таким образом каждая точка (x, y) имеет только одно значение.

import numpy as np

x_coor=135

y_coor=120

grid=np.zeros((x_coor,y_coor)

Есть ли способ сделать это grid[x,y]=(value1,value2), и есть ли лучший способ определить сетку, отличную от массива numpy?


person ironmacaron    schedule 22.05.2019    source источник


Ответы (2)


Вы действительно можете использовать numpy для этого. Одним из способов было бы определить массив 3d как np.zeros((x_coor, y_coor, 2)) и сохранить каждую из координат вдоль последней оси.

Другой способ получить желаемую структуру с помощью numpy может состоять в том, чтобы определить ndarray из tuples и обновить каждую точку указанным способом, то есть grid[x,y] = (value1,value2). Вот как вы можете это сделать:

x_coor=135
y_coor=120

grid = np.zeros((5,3), dtype='i,i')
grid[0,0] = (1,2)
grid[2,2] = (5,1)
grid[1,0] = (3,5)

print(grid)
array([[(1, 2), (0, 0), (0, 0)],
       [(3, 5), (0, 0), (0, 0)],
       [(0, 0), (0, 0), (5, 1)],
       [(0, 0), (0, 0), (0, 0)],
       [(0, 0), (0, 0), (0, 0)]], dtype=[('f0', '<i4'), ('f1', '<i4')])

Если вы хотите обновить несколько значений одновременно, используя несколько координат, вы можете сделать:

grid = np.zeros((5,3), dtype='i,i')

coordinates = np.array([(1,2),(2,2), (0,0)], dtype='i,i')
new_vals = np.array([(12,2),(4,1), (0,9)], dtype='i,i')

grid[tuple(zip(*coordinates))] = new_vals

print(grid)
array([[( 0, 9), ( 0, 0), ( 0, 0)],
       [( 0, 0), ( 0, 0), (12, 2)],
       [( 0, 0), ( 0, 0), ( 4, 1)],
       [( 0, 0), ( 0, 0), ( 0, 0)],
       [( 0, 0), ( 0, 0), ( 0, 0)]], dtype=[('f0', '<i4'), ('f1', '<i4')])

Обратите внимание, что кортежи неизменяемы, поэтому, если вы планируете выполнять операции с этими координатами, вам следует использовать первый подход.

person yatu    schedule 22.05.2019
comment
Я планирую использовать вложенные циклы for (для i в диапазоне (1,x_coor) для j в диапазоне (1,y_cor) для выполнения вычислений для каждой точки. И мне нужно выполнять вычисления для каждой точки сетки - person ironmacaron; 22.05.2019
comment
Что ж, в этом случае я бы придерживался подхода 1, поэтому определял 3D-матрицу и просто индексировал первый или второй элемент на последней оси @ironmacaron - person yatu; 22.05.2019

Краткий ответ на ваш вопрос: вы должны использовать pandas вместо массива numpy. Numpy предназначен для ускорения вычислений массива, поэтому он не позволяет определять каждый элемент массива как список. Однако кадры данных Pandas разрешают операции такого типа. Вот как вы могли бы выполнить такую ​​​​операцию в pandas, и особенно обратите внимание на то, как исходный фрейм данных определяется гибко, чтобы впоследствии им можно было манипулировать для изменения длины списков, содержащихся в каждой ячейке:

import numpy as np
import pandas as pd
df = pd.DataFrame(columns=[0,1,2])

for i in range(5):
df.loc[i,0] = np.arange(i)
df.loc[i,1] = np.arange(i)
df.loc[i,2] = np.arange(i)

print(df.loc[2,2])

Это запись в ячейке (2,2):

array([0, 1])

Что вы можете изменить сейчас, как вам нужно:

df.loc[2,2] = [10,20,30]

А сейчас:

print(df.loc[2,2])

дает тебе:

[10, 20, 30]
person HMReliable    schedule 22.05.2019
comment
Когда я печатаю df для этого примера, он дает количество элементов строки номер-1 в каждой ячейке, а не 1 или 2 значения для всех. Я просмотрел документацию по пандам, но не смог понять, как создать матрицу n*m. Извините, я очень не знаком с Pandas, но я очень заинтригован после прочтения вашего ответа. - person ironmacaron; 22.05.2019
comment
Я создал записи ячеек разной длины, чтобы показать, что фрейм данных может вмещать записи любой длины... вы можете просто заменить df.loc[I,0] = np.arange(i) на df.loc[I, 0] = np.arange(2), чтобы все ячейки имели начальные записи (0,1). После этого вы можете манипулировать любой ячейкой, чтобы получить список любой длины, не обязательно только длины 2. Таким образом, это намного более гибко. - person HMReliable; 22.05.2019