Так что я не верю, что представления памяти действительно поддерживают логическое индексирование в любом случае. Поэтому, чтобы проиндексировать массив, вам всегда нужно будет
np.asarray(mc.data)[mask]
# or
mc.data.base[mask] # if you're sure it's always a view of something that supports boolean indexing)
Я не думаю, что это изменится с обновлением Cython, которое упоминает @ead. Я подозреваю, что причина этого в том, что, вероятно, довольно легко выполнить присваивание (mc.data[mask] = x
), но не очевидно, какой тип должен возвращаться mc.data[mask]
- это не просмотр памяти.
Поэтому, что бы вы ни делали, это будет связано с каким-то грязным кодом.
Для части Назначения для просмотра памяти можно выполнить с помощью
mc.mask = (np.asarray(mc.data) > 0.5).view(np.uint8)
и вернуть его Numpy. массив bool с:
np.asarray(mc.mask).view(np.bool)
ни один из которых не должен включать в себя копирование.
Если бы я это проектировал, я бы оставил просмотры памяти закрытыми (для использования только на Cython)) и имеют обычные атрибуты объекта, которые просто содержат базовые массивы Numpy для интерфейса Python. Вы могли бы использовать property
, чтобы поддерживать их в синхронизации (и выполнять приведение):
cdef class MyClass:
cdef np.uint8_t[:] mask_mview
cdef object _mask
@property
def mask(self):
return np.asarray(self._mask).view(np.bool)
@mask.setter
def mask(self, value):
self._mask = value
self.mask_view = value.view(np.uint8)
# and the same for data
Таким образом, у вас есть представление о памяти, которое можно использовать для вещей, которые хорошо подходят для представлений о памяти (итерируя быстро по элементамэлемент в Cython), доступ к простому массиву Numpy для Python, и эти два синхронизируются (по крайней мере, через интерфейс Python).