Отфильтруйте список 3D Python, используя список или NumPy - PullRequest
1 голос
/ 21 июня 2019

У меня есть список Python 3D. Чтобы сделать его более понятным, список списка, где каждый список является четырехугольной координатой поля. Я должен отфильтровать все поля, которые меньше определенного размера.

Предположим, это список питонов.

box = [[[4, 4], [4, 8], [8, 8], [8, 4]],
      [[8, 8], [8, 16], [16, 16], [16, 8]],
      [[20,16],[20,20],[24,20],[24,16]]
      ...
      ]

Я должен отфильтровать все поля, длина и ширина которых меньше или равны 5.

filtered_box = [[[4, 4], [4, 8], [8, 8], [8, 4]],
                [[20,16],[20,20],[24,20],[24,16]]
               ...
               ]

Это мой текущий код

filtered_box = []
for c in box:
    min_x, min_y = c[0]
    max_x, max_y = c[2]
    if max_x - min_x <= 5 & min_y - max_y <= 5:
        filtered_box.append(c)

Это работает хорошо, но мне нужно более оптимизированное решение. Он может использовать numpy и конвертировать обратно в список python или использовать собственные операции над python в списке. Я использую Python 3.

Ответы [ 2 ]

1 голос
/ 21 июня 2019

Решение с numpy может выглядеть так:

filtered_array = array[
    (np.abs(array[:, 0, 0] - array[:, 3, 0]) < 5) &
    (np.abs(array[:, 0, 1] - array[:, 3, 1]) < 5), :, :]

, где array = np.array(box).

Я думаю, это решение будет значительно быстрее, чем обычный питон, если вы подготовили данные (массив NumPy).Преобразование данных из списка Python в массив NumPy аннулирует любой выигрыш времени.

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

Это понимание списка заменяет вашу конструкцию цикла for:

import numpy as np

box = [
      [[4, 4], [4, 8], [8, 8], [8, 4]],
      [[8, 8], [8, 16], [16, 16], [16, 8]],
      [[20,16],[20,20],[24,20],[24,16]]
      ]

box = np.array(box) # convert to numpy array

# one-liner
filtered = [i for i in box if np.ptp(i[:,0]) <= 5 and np.ptp(i[:,1]) <= 5]

filtered = np.array(filtered) # if you want to convert to a numpy array
...