Как заставить Numpy рассматривать каждую строку / тензор как значение
Многие функции, такие как in1d
а также setdiff1d
предназначены для 1-го массива. Одним из способов применения этих методов к N-мерным массивам является создание numpy
рассматривать каждую строку (что-то более высокое измерение) как значение.
Один из подходов, который я нашел, заключается в следующем: " Получите пересекающиеся строки в двух двумерных массивах" от Джо Кингтона.
Следующий код взят из этого ответа. Задача, с которой столкнулся Джо Кингтон, состояла в том, чтобы обнаружить общие строки в двух массивах A
а также B
пытаясь использовать in1d
,
import numpy as np
A = np.array([[1,4],[2,5],[3,6]])
B = np.array([[1,4],[3,6],[7,8]])
nrows, ncols = A.shape
dtype={'names':['f{}'.format(i) for i in range(ncols)],
'formats':ncols * [A.dtype]}
C = np.intersect1d(A.view(dtype), B.view(dtype))
# This last bit is optional if you're okay with "C" being a structured array...
C = C.view(A.dtype).reshape(-1, ncols)
Я надеюсь, что вы поможете мне с любым из следующих трех вопросов. Во-первых, я не понимаю механизмы этого метода. Можете ли вы попытаться объяснить это мне?
Во-вторых, есть ли другие способы, позволяющие NumPy обрабатывать подмассив как один объект?
Еще один открытый вопрос: есть ли недостатки у подхода Джо? Я имею в виду, может ли обработка строк как значения вызвать некоторые проблемы? Извините, этот вопрос довольно широкий.
1 ответ
Попробуйте опубликовать то, что я узнал. Метод, который использовал Джо, называется структурированными массивами. Это позволит пользователям определять, что содержится в одной ячейке / элементе.
Мы рассмотрим описание первого примера предоставленной документации.
x = np.array([(1,2.,'Hello'), (2,3.,"World")], ... dtype=[('foo', 'i4'),('bar', 'f4'), ('baz', 'S10')])
Здесь мы создали одномерный массив длины 2. Каждый элемент этого массива представляет собой структуру, которая содержит три элемента: 32-разрядное целое число, 32-разрядное число с плавающей запятой и строку длиной 10 или менее.
Не проходя в dtype
Однако мы получим матрицу 2 на 3.
С помощью этого метода мы сможем numpy
обрабатывать массив более высокой размерности как отдельный элемент с правильно установленным dtype
,
Еще один трюк, который продемонстрировал Джо, заключается в том, что для достижения цели нам не нужно создавать новый массив numpy. Мы можем использовать view
функция (см. ndarray.view
) изменить способ numpy
просмотреть данные. Есть раздел Note
раздел в ndarray.view
что я думаю, что вы должны посмотреть, прежде чем использовать метод. У меня нет гарантии, что не будет побочных эффектов. Параграф ниже взят из раздела заметок и, похоже, требует осторожности.
Для a.view(some_dtype), если some_dtype имеет другое количество байтов на запись, чем предыдущий dtype (например, преобразование обычного массива в структурированный массив), то поведение представления не может быть предсказано только по внешнему виду из (показано печатью (а)). Это также зависит от того, как именно хранится в памяти. Следовательно, если a является C-упорядоченным по сравнению с Fortran-упорядоченным, а не определенным как срез или транспонирование и т. Д., Представление может дать разные результаты.
Другая ссылка
https://docs.scipy.org/doc/numpy-1.13.0/reference/arrays.dtypes.html https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.dtype.html