#python #arrays #numpy #vectorization
#python #массивы #numpy #векторизация
Вопрос:
Я хотел бы сделать что-то вроде этого:
>>> y = np.arange(5)
>>> y in (0, 1, 2)
array([True, True, True, False, False])
Этот синтаксис не работает. Каков наилучший способ достичь желаемого результата?
(Я ищу общее решение. Очевидно, что в этом конкретном случае я мог бы сделать y < 3
.)
Я объясню это немного более четко для вас, ребята, поскольку, по крайней мере, несколько человек, похоже, сбиты с толку.
Вот долгий способ добиться желаемого поведения:
new_y = np.empty_like(y)
for i in range(len(y)):
if y[i] in (0, 1, 2):
new_y[i] = True
else:
new_y[i] = False
Я ищу такое поведение в более компактной форме.
Вот другое решение:
new_y = np.array([True if item in (0, 1, 2) else False for item in y])
Опять же, просто ищу более простой способ.
Комментарии:
1.
np.in1d(y, [0,1,2])
Ответ №1:
Хорошим инструментом общего назначения является широковещательное, или «внешнее», сравнение элементов двух массивов:
In [35]: y=np.arange(5)
In [36]: x=np.array([0,1,2])
In [37]: y[:,None]==x
Out[37]:
array([[ True, False, False],
[False, True, False],
[False, False, True],
[False, False, False],
[False, False, False]])
Это выполняет быстрое сравнение между каждым элементом y
и каждым элементом x
. В зависимости от ваших потребностей, вы можете сконденсировать этот массив вдоль одной из осей:
In [38]: (y[:,None]==x).any(axis=1)
Out[38]: array([ True, True, True, False, False])
Предложен комментарий in1d
. Я думаю, что неплохо бы взглянуть на его код. У него есть несколько стратегий в зависимости от относительных размеров входных данных.
In [40]: np.in1d(y,x)
Out[40]: array([ True, True, True, False, False])
In [41]: np.array([True if item in x else False for item in y])
Out[41]: array([ True, True, True, False, False])
Самый быстрый может зависеть от размера входных данных. Начальные списки ваше понимание списка может быть быстрее. Эта версия с чистым списком, безусловно, самая быстрая:
[True if item in (0,1,2) else False for item in (0,1,2,3,4)]
[item in (0,1,2) for item in (0,1,2,3,4)] # simpler
Комментарии:
1. Если кто-нибудь еще окажется здесь позже и увидит комментарий np.in1d, вероятно, лучше проверить np.isin как современного преемника: numpy.org/doc/stable/reference/generated /…
2. @Starman, но посмотрите на его код
3. Я посмотрел на код, и
np.isin
кажется, что он просто вызываетnp.in1d
под капотом? github.com/numpy/numpy/blob/v1.24.0/numpy/lib/… Такжеnp.in1d
документы рекомендуют использоватьnp.isin
.