Получите разные квантили для каждой строки, используя NumPy - PullRequest
0 голосов
/ 02 октября 2018

Я хотел бы использовать np.percentile, чтобы получить разные квантили для каждой строки.

Например, учитывая этот массив из двух строк, я хотел бы получить 20-й процентиль для первой строкии 60-й процентиль для второго.

dat = np.array([[1, 10, 3], [4, -1, 5]])
dat
# array([[ 1, 10,  3],
#        [ 4, -1,  5]])

Начиная с 20-го процентиля:

np.percentile(dat, 0.2, axis=1)
# array([ 1.008, -0.98 ])

И 60-го:

np.percentile(dat, 0.6, axis=1)
# array([ 1.024, -0.94 ])

Исходя из этого,идеальный результат был бы [1.008, -0.94].

Передача вектора по мере того, как квантиль расширяет результат в массив n x n:

np.percentile(dat, [0.2, 0.6], axis=1)
# array([[ 1.008, -0.98 ],
#        [ 1.024, -0.94 ]])

Диагональ этого результата даетправильный результат:

np.percentile(dat, [0.2, 0.6], axis=1).diagonal()
# array([ 1.008, -0.94 ])

Но это слишком дорого для больших массивов.Есть ли способ напрямую рассчитать процентили с соответствующим квантилем для каждой строки?

Ответы [ 2 ]

0 голосов
/ 02 октября 2018

Если нет конфликтов с типами данных, вы можете объединить процентили и данные, а затем использовать np.apply_along_axis, чтобы отделить процентиль от данных:

def percentile_qarray_np(dat, q):
  return np.apply_along_axis(
    lambda x: np.percentile(x[1:], x[0]),
    1,
    np.concatenate([np.array(q)[:, np.newaxis], dat], axis=1)
  )

Например,:

n = 10
percentiles = np.linspace(0, 100, n)
a = np.arange(n**2).reshape(n, n)
print(percentile_qarray_np(a, percentiles))

Теперь это пакет synthimpute.

0 голосов
/ 02 октября 2018

Вы можете использовать apply после преобразования массива в DataFrame с желаемым квантилем в качестве столбца:

def percentile_qarray_df(dat, q):
  # dat: numpy array.
  # q: Vector with the same number of rows as dat.
  df = pd.DataFrame(dat)
  df['q'] = q
  return df.apply(lambda x: np.percentile(x.drop('q'), x.q), axis=1)

Например:

percentile_qarray_df(dat, [0.2, 0.6])
# 0    1.008
# 1   -0.940
# dtype: float64

Это все ещедовольно медленно, хотя.

...