Проблема с подклассом numpy ndarray

Я хотел бы подклассифицировать numpy ndarray. Однако я не могу изменить массив. Почему self = ... не меняет массив? Благодарю.

 import numpy as np class Data(np.ndarray): def __new__(cls, inputarr): obj = np.asarray(inputarr).view(cls) return obj def remove_some(self, t): test_cols, test_vals = zip(*t) test_cols = self[list(test_cols)] test_vals = np.array(test_vals, test_cols.dtype) self = self[test_cols != test_vals] # Is this part correct? print len(self) # correct result z = np.array([(1,2,3), (4,5,6), (7,8,9)], dtype=[('a', int), ('b', int), ('c', int)]) d = Data(z) d.remove_some([('a',4)]) print len(d) # output the same size as original. Why? 

3 Solutions collect form web for “Проблема с подклассом numpy ndarray”

Возможно, это функция, а не метод:

 import numpy as np def remove_row(arr,col,val): return arr[arr[col]!=val] z = np.array([(1,2,3), (4,5,6), (7,8,9)], dtype=[('a', int), ('b', int), ('c', int)]) z=remove_row(z,'a',4) print(repr(z)) # array([(1, 2, 3), (7, 8, 9)], # dtype=[('a', '<i4'), ('b', '<i4'), ('c', '<i4')]) 

Или, если вы хотите, чтобы это как метод,

 import numpy as np class Data(np.ndarray): def __new__(cls, inputarr): obj = np.asarray(inputarr).view(cls) return obj def remove_some(self, col, val): return self[self[col] != val] z = np.array([(1,2,3), (4,5,6), (7,8,9)], dtype=[('a', int), ('b', int), ('c', int)]) d = Data(z) d = d.remove_some('a', 4) print(d) 

Основное различие здесь заключается в том, что remove_some не пытается изменить self , он просто возвращает новый экземпляр Data .

Причина, по которой вы не получаете remove_some результат, заключается в том, что вы повторно назначаете self в метод remove_some . Вы просто создаете новую локальную переменную self . Если ваша форма массива не изменилась, вы могли бы просто сделать self [:] = … и вы могли бы сохранить ссылку на self и все было бы хорошо, но вы пытаетесь изменить форму self . Это означает, что нам нужно перераспределить некоторую новую память и изменить там, где мы указываем, когда будем ссылаться на self .

Я не знаю, как это сделать. Я думал, что это может быть достигнуто __array_finalize__ или __array__ или __array_wrap__ . Но все, что я пробовал, падает.

Теперь есть еще один способ сделать это, не подкласса ndarray . Вы можете создать новый класс, в котором хранится атрибут ndarray, а затем переопределить все обычные __add__ , __mul__ и т. Д. Что-то вроде этого:

 Class Data(object): def __init__(self, inarr): self._array = np.array(inarr) def remove_some(x): self._array = self._array[x] def __add__(self, other): return np.add(self._array, other) 

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

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

Я попытался сделать то же самое, но это действительно очень сложно для подкласса ndarray.

Если вам нужно только добавить некоторые функции, я бы предложил создать класс, который хранит массив как атрибут.

 class Data(object): def __init__(self, array): self.array = array def remove_some(self, t): //operate on self.array pass d = Data(z) print(d.array) 
  • Укладывание многоуровневых репаратов без потери их повторяемости
  • Сортировка массива python / повторение по столбцу
  • Получить атрибуты recarray / columns python
  • Преобразование структурированного массива в обычный массив NumPy
  • Python - лучший язык программирования в мире.