Поиск в массивах numpy

#python #arrays #numpy #search

#python #массивы #numpy #Поиск

Вопрос:

Я хочу создать массив с известными координатами из существующих данных, как избежать всех этих циклов, чтобы ускорить его? Пробовал с np.where, приблизился, но не попал туда. Спасибо!

 import numpy as np
import matplotlib.pyplot as plt

x = np.array([[0, 1, 3, 6], [0, 1, 2, 4], [0, 1, 2, 3]])
y = np.array([[0, 2, 0, 1], [1, 2, 1, 1], [2, 3, 2, 4]])
z = np.array([[100, 100, 100, 100], [100, 150, 100, 100], [100, 100, 100, 200]])

xx = np.arange(np.min(x), np.max(x)   1, 1)
yy = np.arange(np.min(y), np.max(y)   1, 1)
grid_x, grid_y = np.meshgrid(xx, yy)

L1, C1 = x.shape
L2, C2 = grid_x.shape
v = np.zeros((L2, C2))
n = np.zeros((L2, C2))

for l2 in range(L2):
    for c2 in range(C2):
        for l1 in range(L1):
            for c1 in range(C1):
                if grid_x[l2, c2] == x[l1, c1] and grid_y[l2, c2] == y[l1, c1]:
                    v[l2, c2] = v[l2, c2]   z[l1, c1]
                    n[l2, c2] = n[l2, c2]   1

v = v/n

plt.imshow(v)
plt.show()
  

Комментарии:

1. добавьте фактический результат и ожидаемый или желаемый результат

2. Это возвращает желаемый результат, просто слишком медленно для работы с тысячами строк и столбцов.

3. Не могли бы вы подробнее рассказать о «подобрался близко, но не попал туда».

Ответ №1:

Есть 2 способа ускорить это:

  1. вы можете создавать большие и уродливые 4-размерные маски и применять их к своим сеткам (играя с np.newaxis и == из 2 массивов np.
  2. вы можете использовать Numba (http://numba.pydata.org/numba-doc/0.17.0/user/jit.html ) и вам вообще не нужно переписывать свой код. В основном он использует jit-компиляцию и делает ваш код почти таким же быстрым, как код numpy. Все, что вам нужно, это просто обернуть вашу функцию @jit декодератором. Обратите внимание, что не все функции могут быть скомпилированы таким образом. Вероятно (не уверен), вам нужно было бы переместить вложенные циклы в другую функцию и обернуть ее @jit .

Ответ №2:

Частичное улучшение, пока сосредоточенное на n , количестве совпадений.

 import numpy as np
#import matplotlib.pyplot as plt

x = np.array([[0, 1, 3, 6], [0, 1, 2, 4], [0, 1, 2, 3]])
y = np.array([[0, 2, 0, 1], [1, 2, 1, 1], [2, 3, 2, 4]])
z = np.array([[100, 100, 100, 100], [100, 150, 100, 100], [100, 100, 100, 200]])

xx = np.arange(np.min(x), np.max(x)   1, 1)
yy = np.arange(np.min(y), np.max(y)   1, 1)
grid_x, grid_y = np.meshgrid(xx, yy)

L1, C1 = x.shape
L2, C2 = grid_x.shape
v = np.zeros((L2, C2),int)
n = np.zeros((L2, C2),int)

for l2 in range(L2):
    for c2 in range(C2):
        for l1 in range(L1):
            for c1 in range(C1):
                if grid_x[l2, c2] == x[l1, c1] and grid_y[l2, c2] == y[l1, c1]:
                    #v[l2, c2]  = z[l1, c1]
                    n[l2, c2]  = 1

# with broadcasting create 4d arrays, matching x and y with their grids
X = grid_x[:,:,None,None]==x[None,None,:,:]
Y = grid_y[:,:,None,None]==y[None,None,:,:]
XY = X amp; Y
XY = XY.sum(axis=(2,3))

#v = v/n
print(x)
print(y)
print(n)

print(XY)
  

XY Матчи n .

 1032:~/mypy$ python3 stack63844601.py 
[[0 1 3 6]
 [0 1 2 4]
 [0 1 2 3]]
[[0 2 0 1]
 [1 2 1 1]
 [2 3 2 4]]
[[1 0 0 1 0 0 0]             # n
 [1 0 1 0 1 0 1]
 [1 2 1 0 0 0 0]
 [0 1 0 0 0 0 0]
 [0 0 0 1 0 0 0]]
[[1 0 0 1 0 0 0]              # XY
 [1 0 1 0 1 0 1]
 [1 2 1 0 0 0 0]
 [0 1 0 0 0 0 0]
 [0 0 0 1 0 0 0]]
  

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

grid_x и grid_y вероятно, это могут быть sparse версии, хотя это не экономит память в промежуточных массивах 4d.

Я все еще не до конца понял, что должен делать этот поиск. На данный момент это своего рода подход грубой силы, использующий довольно поверхностное понимание ваших 4-уровневых вложенных циклов.

Комментарии:

1. Это проблема с сеткой, но без интерполяции. Есть 3 массива (их можно было бы сгладить, и у нас было бы только 2 цикла for), которые имеют x, y и z. Значения x и y являются точными значениями в узлах сетки, мы могли бы легко перейти от значений к индексам. Сетка строится из максимальных и минимальных значений x и y. Тогда возникает вопрос о том, чтобы поместить значения z в правильное место и выполнить среднее значение, когда в одном и том же месте их несколько.