Как проверить, содержит ли массив вложенный массив без циклов for, и получить индексы, где True? - PullRequest
0 голосов
/ 01 мая 2019

У меня есть два массива - один содержит все точки данных, а другой содержит некоторую выборку точек данных.Я хотел бы получить логические массивы (которые позже будут использоваться в качестве индексов), которые показывают, содержится ли каждая точка выборки в исходном массиве всех точек данных.Я пытаюсь использовать подход, который будет работать независимо от используемых размеров массива.Я успешно сделал это, но хотел бы использовать более простой (то есть векторизованный без цикла for) подход.Ниже приведен краткий пример:

## ALL DATA POINTS: (xi, yi, zi)
p1 = np.array([1, 2, 3])
p2 = np.array([4, 5, 6])
p3 = np.array([2, 3, 4])
p4 = np.array([7, 8, 5])
points = np.array([p1, p2, p3, p4])

## SAMPLE OF DATA (xi, yi, zi)
s1 = np.array([1, 2, 3])
s2 = np.array([4, 6, 5])
s3 = np.array([7, 8, 9])
samples = np.array([s1, s2, s3])

Итак, данные выглядят следующим образом:

print("\nDATA POINTS ({}):\n{}\n".format(points.shape, points))
print("\nSAMPLE POINTS ({}):\n{}\n".format(samples.shape, samples))

DATA POINTS ((4, 3)):
[[1 2 3]
 [4 5 6]
 [2 3 4]
 [7 8 5]]


SAMPLE POINTS ((3, 3)):
[[1 2 3]
 [4 6 5]
 [7 8 9]]

Итак, точка (1, 2, 3) является первой точкой данных и первой точкой выборки и т. Д.,Приведенная ниже функция использует цикл for, чтобы определить, содержатся ли точки выборки в исходном наборе данных.

f2 = lambda points, samples : np.array([sample == points for sample in samples])
ans2 = f2(points, samples)

Полученный логический массив выглядит следующим образом:

for sample, arr in zip(samples, ans2):
    print("\n-- SAMPLE POINT: {}\n".format(sample))
    print("\n .. CONTAINMENT ARRAY ({}):\n{}\n".format(arr.shape, arr))
    res = np.all(arr, axis=1)
    print("\n .. POINTS CONTAINED ({}):\n{}\n".format(res.shape, res))


-- SAMPLE POINT: [1 2 3]


 .. CONTAINMENT ARRAY ((4, 3)):
[[ True  True  True]
 [False False False]
 [False False False]
 [False False False]]


 .. POINTS CONTAINED ((4,)):
[ True False False False]


-- SAMPLE POINT: [4 6 5]


 .. CONTAINMENT ARRAY ((4, 3)):
[[False False False]
 [ True False False]
 [False False False]
 [False False  True]]


 .. POINTS CONTAINED ((4,)):
[False False False False]


-- SAMPLE POINT: [7 8 9]


 .. CONTAINMENT ARRAY ((4, 3)):
[[False False False]
 [False False False]
 [False False False]
 [ True  True False]]


 .. POINTS CONTAINED ((4,)):
[False False False False]

Этот результат верен.

Однако я думаю, что должен быть более простой метод для достижения этого результата.Я посмотрел на numpy.isin ;однако результаты не идентичны.Ниже моя попытка:

f1 = lambda points, samples : np.isin(samples, points)
ans1 = f1(points, samples)

Этот результат выглядит следующим образом:

print("\n*- ANS 1 ({}):\n{}\n".format(ans1.shape, ans1))

*- ANS 1 ((3, 3)):
[[ True  True  True]
 [ True  True  True]
 [ True  True False]]

Из этого результата я вижу, что массив проверяет значения 4, 5и 6 без учета их соответствующих мест размещения в массиве, поэтому True возвращается для каждого элемента второй строки.

Как я могу изменить этот подход или начать заново, чтобы проверить, если каждыйвложенный массив точек выборки содержится в массиве всех точек данных более простым способом?

...