Как я могу преобразовать массив значений в соответствующий массив индексов, используя numpy векторизацию? - PullRequest
0 голосов
/ 30 января 2020

У меня есть numpy массив пар сэмплов (2-D) и массив сэмплов (1-D). Я хочу преобразовать пары сэмплов в соответствующий массив (т.е. 2-D), представляющий индексы массива сэмплов. Есть ли более быстрое решение, чем то, что я уже использовал?

import numpy as np
pair_list = np.array([['samp1', 'samp4'],
                ['samp2', 'samp7'],
                ['samp2', 'samp4']])
samples = np.array(['samp0', 'samp1', 'samp2', 'samp3', 'samp4', 'samp5',
                 'samp6', 'samp7', 'samp8', 'samp9'])

vfunc = np.vectorize(lambda s: np.where(samples == s)[0])
pair_indices = vfunc(pair_list)

In [180]: print(pair_indices)
[[1 4]
 [2 7]
 [2 4]]

Ответы [ 2 ]

2 голосов
/ 30 января 2020

Я предлагаю вам использовать словари из-за их производительности сложность времени .

>>> import numpy as np
>>> pair_list = np.array([['samp1', 'samp4'],
                ['samp2', 'samp7'],
                ['samp2', 'samp4']])
>>> samples = {'samp0':0, 'samp1':1, 'samp2':2, 'samp3':3, 'samp4':4, 'samp5':5,
                 'samp6':6, 'samp7':7, 'samp8':8, 'samp9':9}
>>> vfunc = np.vectorize(lambda x: samples[x])
>>> pair_indices = vfunc(pair_list)
>>> print(pair_indices)
[[1 4]
 [2 7]
 [2 4]]
1 голос
/ 30 января 2020
pair_list = np.array([['samp1', 'samp4'],
            ['samp2', 'samp7'],
            ['samp2', 'samp4']])
samples = np.array(['samp0', 'samp1', 'samp2', 'samp3', 'samp4', 'samp5',
             'samp6', 'samp7', 'samp8', 'samp9'])

def f1(pair_list,samples):
    vfunc = np.vectorize(lambda s: np.where(samples == s)[0])
    return vfunc(pair_list)

def f2(pair_list,samples):
    d = dict()
    for idx,el in enumerate(samples): d[el]=idx
    return np.array([d[el] for row in pair_list for el in row]).reshape(pair_list.shape[0],2)

f2 выглядит неуклюже, но ...

timeit f1(pair_list,samples)
25.7 µs ± 78 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

timeit f2(pair_list,samples)
9.09 µs ± 68.5 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

Попробуйте на своей машине и посмотрите, как это будет для вас! Конечно, было бы еще лучше, если бы у вас была возможность повторно использовать samples, поскольку в этом случае вам нужно конвертировать samples в dict один раз.

Редактировать: Гораздо, намного лучше векторизовать dict доступ, как предлагает Mohsen_Fatemi, даже если samples нельзя использовать повторно.

def f3(pair_list,samples):
    d = dict()
    for idx,el in enumerate(samples): d[el]=idx
    vfunc = np.vectorize(lambda x: d[x])
    return vfunc(pair_list)

timeit f3
16.1 ns ± 0.0138 ns per loop (mean ± std. dev. of 7 runs, 100000000 loops each)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...