Как я могу перебрать матрицу и заполнить значения? - PullRequest
1 голос
/ 27 июня 2019

У меня есть два фрейма данных, в одном из которых есть два столбца (список ребер графа), а в другом фрейме данных - местоположение этих точек. Я хочу выполнить поиск среди первого фрейма данных и заменить координаты x и y каждой точки вместо точек в двух отдельных фреймах данных. Сначала я превратил фреймы данных в массив numpy. Например, предположим, что у нас есть xx в качестве нашего списка ребер и yy в качестве координат, как показано ниже:

xx= np.array([(4,2),(3,5)])
yy=np.array([(2,6,7),(5,5,6),(4,8,9),(3,2,2)])

, поэтому xx - это наши граничные точки, а yy - координаты каждой точки (например, точка 4 имеет значение x 8 и значение y 9) Затем я попытался заменить узлы с соответствующими значениями координат x:

zz=[]
for i in np.nditer(xx,order='F'):
    cc=np.where(yy[:,0]==i)
    zz.append(cc[0][0])
zz=np.array(zz)
q=[]
for i in range(xx.size):
    q.append(yy[zz[i],1])
xcoordinates=np.array(q).reshape(int(xx.size/2),2)

Однако результаты не корректны после изменения формы:

array([[8, 2],
       [6, 5]])

Пожалуйста, дайте мне знать, как я могу получить эти результаты для x:

[8,6]
[2,5]

Я довольно новичок в python и не могу понять сложные коды.

Ответы [ 2 ]

0 голосов
/ 28 июня 2019

Давайте определим небольшую вспомогательную функцию, которая сопоставляет значение xx с первым столбцом yy и возвращает значение из второго.

def foo(x):
    return yy[yy[:,0]==x, 1].item()

и протестируйте пару значений:

In [101]: foo(3)                                                                                     
Out[101]: 2
In [102]: foo(4)                                                                                     
Out[102]: 8

Вместо nditer, давайте использовать xx.flat в качестве 1d итератора.

In [103]: for x in xx.flat: 
     ...:     print(foo(x)) 
     ...:                                                                                            
8
6
2
5

Или сделать то же самое в понимании списка:

In [104]: [foo(x) for x in xx.flat]                                                                  
Out[104]: [8, 6, 2, 5]

и используйте reshape для приведения его обратно в массив той же формы, что и xx:

In [105]: np.reshape([foo(x) for x in xx.flat],xx.shape)                                             
Out[105]: 
array([[8, 6],
       [2, 5]])

Мне также нравится frompyfunc как способ применения скалярной функции к элементам массива. В тестах это может быть в 2 раза быстрее, чем более прямые итерации, но все же легко использовать без ошибок:

In [106]: np.frompyfunc(foo,1,1)(xx)                                                                 
Out[106]: 
array([[8, 6],
       [2, 5]], dtype=object)

Но другой ответ показывает, как сделать то же самое без итерации уровня Python.

Еще один «векторизованный» подход:

Сравните все значения xx с 1-м столбцом yy. В результате получается логический массив 3d:

In [107]: xx[...,None]==yy[:,0]                                                                      
Out[107]: 
array([[[False, False,  True, False],
        [ True, False, False, False]],

       [[False, False, False,  True],
        [False,  True, False, False]]])

where - это кортеж из 3 элементов. 2 элемента индекса xx, последний yy:

In [108]: np.where(xx[...,None]==yy[:,0])                                                            
Out[108]: (array([0, 0, 1, 1]), array([0, 1, 0, 1]), array([2, 0, 3, 1]))
In [109]: yy[np.where(xx[...,None]==yy[:,0])[2],1]                                                   
Out[109]: array([8, 6, 2, 5])
0 голосов
/ 27 июня 2019

Требуется некоторая работа со вторым массивом, но вы можете создать массив поиска, который можно индексировать с помощью xx.

u = np.empty(yy[:, 0].max() + 1, dtype=yy.dtype)
u[yy[:, 0]] = yy[:, 1]

u[xx]

array([[8, 6],
       [2, 5]])

Есть несколько предположений, которые этот ответ делает, которые вы должны принять во внимание.

1) yy должен быть уникальным и иметь целое число dtype

2) xx должен следовать yy.min() < xx < yy.max(), иначе вы получите IndexError

3) Все значения xx должны быть в y[:, 0], иначе вы получите ненужные значения обратно в отображение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...