Лучший способ получить наибольшее значение в матричном массиве в python - PullRequest
0 голосов
/ 30 марта 2020

Мне нужно проверить самое высокое значение массива, но в моем случае он принимает long:

Мой массив имеет 3 значения: X, Y, Значение

[
 [1,1,36],
 [1,2,36.5],
 [1,3,36.5],
 [1,4,36.5],
 [1,5,36.5],
 [2,1,36.5],
 [2,2,36.5],
 [2,3,36.5],
 [2,4,36.5],
 [2,5,36.5],
 [3,1,36.5],
 [3,2,36.5],
 [3,3,36.5],
 [3,4,36.5],
 [3,5,36.5],
]

обратите внимание, что мой массив - это топор, значение y для пикселя, а последняя информация - это float значение для него.

, но это небольшой пример i. Im мой реальный случай, у меня будет 300.000 итенов в моем массиве. Я хотел бы получить самое высокое значение внутри начальных точек x, y и конечных точек x, y.

Я выполнил функцию for, но ее выполнение занимает много времени.

кто-то может помогите мне?

#

Теперь у меня есть другой массив, мне нужно получить самое высокое значение, где у меня есть только значения [x,y], и чтобы получить температуру, я должен получить это:

value = image_data[x,y]

in следующий пример от DarrylG. Я не знаю, как изменить его, чтобы он работал таким образом.

Я пытался изменить эту строку

return max(lst[index_lo:index_hi+1], key=lambda item: item[2])

на

return max(lst[index_lo:index_hi+1], key=lambda item: lst[0,1])

, но это не сработало.

1 Ответ

4 голосов
/ 30 марта 2020

Предположение 1

Поскольку использование {} не имеет смысла, я предполагаю, что ваши значения:

my_lst = [
 [1,1,36],
 [1,2,36.5],
 [1,3,36.5],
 [1,4,36.5],
 [1,5,36.5],
 [2,1,36.5],
 [2,2,36.5],
 [2,3,36.5],
 [2,4,36.5],
 [2,5,36.5],
 [3,1,36.5],
 [3,2,36.5],
 [3,3,36.5],
 [3,4,36.5],
 [3,5,36.5],
]

Предположение 2

Первые два значения (т.е. X, Y) упорядочены в порядке возрастания (как в данных вашего примера).

Предположение 3

Из ваших комментариев реальная проблема, которую вы пытаетесь решить, - найти максимальное значение в ограниченном диапазоне значений (X, Y).

Решение

Мы не можем просто использовать ( Примеры, использующие ключ max ):

print(max(my_lst, key=lambda x: x[2]))

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

Нам нужен быстрый метод для поиска индекса начала и конца в нашем списке кортежей.

Подсписок определяется индексами (X, Y) места начала / остановки, такие как: start: (2, 1), fini sh: (3, 4).

Мы используем метод из здесь , который допускает двоичный файл поиск для поиска индексов запуска и остановки.

from bisect import bisect_left
class KeyList(object):
    # bisect doesn't accept a key function, so we build the key into our sequence.
    def __init__(self, l, key):
        self.l = l
        self.key = key
    def __len__(self):
        return len(self.l)
    def __getitem__(self, index):
        return self.key(self.l[index])

def find_max(lst, lo, hi):
  " Finds max within sublist of lo to hi tuples "

  # Binary search to find index of lo and hi pixel tuples
  index_lo = bisect_left(KeyList(lst, lambda y: (y[0], y[1])), start)
  index_hi = bisect_left(KeyList(lst, lambda y: (y[0], y[1])), finish)

  # Use slice to get sublist
  # Max based upon key which uses 3rd element of tuples
  return max(lst[index_lo:index_hi+1], key=lambda item: item[2])

Использование

print(find_max(my_lst, (2,1), (3,4)))

Вывод

[2, 1, 36.5]

Дополнительный вопрос

В вашем дополнительном вопросе данные на самом деле представляют собой двумерный массив или сетку точек.

Для этого типа данных нам не требуется двоичный поиск, чтобы найти где данные начинаются и заканчиваются.

def find_max_grid(lst, lo, hi):
  " Find max within a 2d array given starting and stopping tuples "
  def max_with_index(row):
    " Finds max in a row "
    return max(enumerate(row), key=lambda v: v[1])

  r1, c1 = lo  # Starting row & column
  r2, c2 = hi  # Ending row & column

  max_row, max_col, max_val = -1, -1, 0  # Initial
  for r, row in enumerate(lst[r1:r2+1], start = r1):
    if r == r1:
      index, val  = max_with_index(row[c1:])
    elif r == r2:
      index, val = max_with_index(row[:c2+1])
    else:
      index, val = max_with_index(row)

    if val > max_val:
      max_row = r
      max_col = index
      max_val = val

  return (max_row, max_col), max_val

Использование

image_data = [
  [11, 12, 5, 2], 
  [15, 6, 10, 11], 
  [10, 8, 12, 5], 
  [12, 15, 8, 6]
  ]

# find max from row 1, column 2
# to            row 3, column 4
# rows and columns numbered are 0, 1, 2, ...
print(find_max_grid(image_data, [1, 2], [3, 4]))

Выход

((3, 1), 15)  # row 3, column 1 with value 15
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...