Должен ли я форсировать все в массив numpy только потому, что я хочу удобную индексацию и нарезку? - PullRequest
0 голосов
/ 11 февраля 2020

В моем текущем проекте мне нужно отслеживать несколько списков, в которых хранятся свойства коллекции «вещей». Списки упорядочены таким образом, что i-й элемент каждого списка представляет собой свойство i-й «вещи».

Мои «вещи» на самом деле являются двоичными изображениями в OpenCV. У меня есть один список, где каждый элемент представляет собой массив 2D numpy, представляющий двоичное изображение. У меня есть еще один список с контурами этих двоичных изображений. Еще один с иерархией этих контуров. Еще один с индексом, который помогает мне заказать эти вещи. И еще один с ... Ну, даже если вы не используете OpenCV, вы, вероятно, поймете точку.

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

Вот что я имею в виду:

ls1 = [[1,2,3], [1,2]]
np.array(ls1)
>>> array([list([1, 2, 3]), list([1, 2])], dtype=object)

ls2 = [[1,2,3], [1,2,3]]
np.array(ls2)
>>> array([[1, 2, 3],
       [1, 2, 3]])

Чтобы добраться до точки , я чувствую, что numpy не хотел, чтобы я использовал это таким образом. Я делаю разумную вещь здесь? Или есть лучший способ отслеживать несколько списков параллельно и легко извлекать / переназначать их фрагменты?

РЕДАКТИРОВАТЬ

По запросу здесь минимальный пример того, что я действительно пытаюсь сделать.

# I have a list of binary images, each with different size
# pretend there are 100 of them
ls_binaries = [binary1, binary2, binary100]


# I want to know if they have some property "foo"
ls_has_foo = [has_foo(binary) for binary in ls_binaries]

# At some other point I want to know if they have some property "bar"
ls_has_bar = [has_bar(binary) for binary in ls_binaries]

# Maybe at some point later I want to retrieve all binaries 
# which have foo but not bar
# but I can only do it this way if binaries is a numpy array
arr_binaries = np.array(ls_binaries)
binaries_which_have_foo_but_not_bar = arr_binaries[np.bitwise_and(ls_has_foo, ~ls_has_bar)]

# And maybe I'll want to do it again at some other point later
# but in a slightly different way.

И еще один пример из комментариев: Вот что я делаю, чтобы упорядочить набор контуров слева направо. Контуры могут иметь различную длину, но это прекрасно работает:

x_coords = np.array([np.min(el[:,:,0]) for el in contours])
cnt_sort = np.argsort(x_coords)

1 Ответ

0 голосов
/ 11 февраля 2020

Абстрагирование вашего минимального примера:

Два ваших has теста выдают логические списки:

In [331]: l1, l2 = [True,False,False], [True,True,False]   

Их можно комбинировать с функцией массива:

In [332]: np.bitwise_and(l1,l2)          
Out[332]: array([ True, False, False])


In [333]: ls = ['foo','bar','baz']                                                             

индексирование dtype объекта:

In [334]: np.array(ls,object)                                                                  
Out[334]: array(['foo', 'bar', 'baz'], dtype=object)
In [335]: np.array(ls,object)[_332]                                                            
Out[335]: array(['foo'], dtype=object)

эквивалентный список 'indexing':

In [336]: [x for x,y in zip(ls, _332) if y]                                                    
Out[336]: ['foo']

эквивалент списка для bitwise_and:

In [338]: [(x and y) for x,y in zip(l1,l2)]                                                    
Out[338]: [True, False, False]

Если вы начинаете со списков, часто лучше придерживаться списков. Операции с массивами, такие как bitwise_and и индексация, могут быть быстрыми, но сначала создание массивов занимает некоторое время.

Массивы объектов типа d занимают неудобное положение между списками и массивами.

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