python питон Numpy: для каждого элемента в одном массиве найдите индекс в другом массиве



индекс элемента массива python (5)

Более прямое решение, которое не ожидает сортировки массива.

import pandas as pd
A = pd.Series(['amsterdam', 'delhi', 'chromepet', 'tokyo', 'others'])
B = pd.Series(['chromepet', 'tokyo', 'tokyo', 'delhi', 'others'])

# Find index position of B's items in A
B.map(lambda x: np.where(A==x)[0][0]).tolist()

Результат:

[2, 3, 3, 1, 4]

У меня два массива 1D, x & y, один меньше, чем другой. Я пытаюсь найти индекс каждого элемента y в x.

Я нашел два наивных способа сделать это, первый - медленный, а второй - интенсивный.

Медленный путь

indices= []
for iy in y:
    indices += np.where(x==iy)[0][0]

Память

xe = np.outer([1,]*len(x), y)
ye = np.outer(x, [1,]*len(y))
junk, indices = np.where(np.equal(xe, ye))

Существует ли более быстрый или менее интенсивный подход к памяти? В идеале поиск воспользовался бы тем фактом, что мы ищем не что-то в списке, но многое, и, следовательно, немного более поддаемся распараллеливанию. Бонусные баллы, если вы не предполагаете, что каждый элемент y фактически находится в x.


Answer #1

Как насчет этого?

Он предполагает, что каждый элемент y находится в x, (и возвращает результаты даже для элементов, которые не являются!), Но он намного быстрее.

import numpy as np

# Generate some example data...
x = np.arange(1000)
np.random.shuffle(x)
y = np.arange(100)

# Actually preform the operation...
xsorted = np.argsort(x)
ypos = np.searchsorted(x[xsorted], y)
indices = xsorted[ypos]

Answer #2

Я хочу предложить однострочное решение:

indices = np.where(np.in1d(x, y))[0]

Результатом является массив с индексами для массива x, который соответствует элементам из y, которые были найдены в x.

Его можно использовать без numpy.where, если это необходимо.


Answer #3

Пакет numpy_indexed (отказ от ответственности: я его автор) содержит функцию, которая выполняет именно это:

import numpy_indexed as npi
indices = npi.indices(x, y, missing='mask')

В настоящее время он вызывает KeyError, если не все элементы из y присутствуют в x; но, возможно, я должен добавить kwarg, чтобы можно было пометить такие предметы с -1 или что-то еще.

Он должен иметь такую ​​же эффективность, как и принятый в настоящее время ответ, поскольку реализация выполняется по аналогичным направлениям. Однако numpy_indexed более гибкий, а также позволяет, например, искать индексы строк многомерных массивов.

EDIT: изменил обработку отсутствующих значений; теперь «отсутствующий» kwarg можно установить с помощью «рейза», «игнорирования» или «маски». В последнем случае вы получите маскированный массив той же длины y, на который вы можете вызвать .compressed (), чтобы получить действительные индексы. Обратите внимание, что есть также npi.contains (x, y), если это все, что вам нужно знать.


Answer #4

Как сказал Джо Кингтон, searchsorted() может быстро искать элемент. Чтобы иметь дело с элементами, которые не находятся в x, вы можете проверить результат поиска с помощью оригинала y и создать маску-массив:

import numpy as np
x = np.array([3,5,7,1,9,8,6,6])
y = np.array([2,1,5,10,100,6])

index = np.argsort(x)
sorted_x = x[index]
sorted_index = np.searchsorted(sorted_x, y)

yindex = np.take(index, sorted_index, mode="clip")
mask = x[yindex] != y

result = np.ma.array(yindex, mask=mask)
print result

результат:

[-- 3 1 -- -- 6]




indexing