NumPy, SciPy - как рассчитать z-оценку для подмножеств массива? - PullRequest
0 голосов
/ 31 марта 2020

Используя массив a, приведенный ниже, в качестве примера, я ищу масштабируемый способ вычисления z показателя из последних 2 столбцов a[:, 3:] отдельно для каждого значения в третьем столбце a[:,2]

In [52]: import numpy as np; from scipy import stats

In [53]: a = np.array([[0., 0., 0., 1., 2.], [ 0.,  0.,  1.,  3.,  4.], [ 1.,  0.,
    ...:   0.,  5.,  6.], [1.,  0.,  1.,  7.,  8.], [ 2.,  0., 0.,  9.,  6.], [2.,
    ...:   0.,  1.,  8.,  9.], [ 3.,  np.NaN,  np.NaN,  np.NaN,  np.NaN]])

In [54]: a
Out[54]:
array([[ 0.,  0.,  0.,  1.,  2.],
       [ 0.,  0.,  1.,  3.,  4.],
       [ 1.,  0.,  0.,  5.,  6.],
       [ 1.,  0.,  1.,  7.,  8.],
       [ 2.,  0.,  0.,  9.,  6.],
       [ 2.,  0.,  1.,  8.,  9.],
       [ 3., nan, nan, nan, nan]])

Для случая, когда третий столбец равен 0 a[:,2] == 0, я могу рассчитать его с помощью

In [48]: np.fromfunction(lambda i, j: stats.zscore(a[a[:,2] == 0][:,3:]), (1, 1))
Out[48]:
array([[-1.22474487, -1.41421356],
       [ 0.        ,  0.70710678],
       [ 1.22474487,  0.70710678]])

, а для случая, когда третий столбец равен 1 a[:,2] == 1 Я могу вычислить это с помощью

In [49]: np.fromfunction(lambda i, j: stats.zscore(a[a[:,2] == 1][:,3:]), (1, 1))
Out[49]:
array([[-1.38873015, -1.38873015],
       [ 0.46291005,  0.46291005],
       [ 0.9258201 ,  0.9258201 ]])

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

Out[62]:
array([[ 0.        ,  0.        ,  0.        ,  1.        ,  2.        ,
        -1.22474487, -1.41421356],
       [ 0.        ,  0.        ,  1.        ,  3.        ,  4.        ,
        -1.38873015, -1.38873015],
       [ 1.        ,  0.        ,  0.        ,  5.        ,  6.        ,
         0.        ,  0.70710678],
       [ 1.        ,  0.        ,  1.        ,  7.        ,  8.        ,
         0.46291005,  0.46291005],
       [ 2.        ,  0.        ,  0.        ,  9.        ,  6.        ,
         1.22474487,  0.70710678],
       [ 2.        ,  0.        ,  1.        ,  8.        ,  9.        ,
         0.9258201 ,  0.9258201 ],
       [ 3.        ,         nan,         nan,         nan,         nan,
                nan,         nan]])

1 Ответ

1 голос
/ 31 марта 2020

вам нужно создать массив с тем же числом столбцов, что и a и использовать np.column_stack для их объединения

z1 = np.fromfunction(lambda i, j: stats.zscore(a[a[:,2] == 0][:,3:]), (1, 1))
z2 = np.fromfunction(lambda i, j: stats.zscore(a[a[:,2] == 1][:,3:]), (1, 1))
z=np.zeros((a.shape[0],z1.shape[1]))*np.nan
z[::2][:z1.shape[0]]=z1
z[1::2][:z2.shape[0]]=z2
arr1 = np.column_stack((a,z))
arr1
array([[ 0.        ,  0.        ,  0.        ,  1.        ,  2.        ,
        -1.22474487, -1.41421356],
       [ 0.        ,  0.        ,  1.        ,  3.        ,  4.        ,
        -1.38873015, -1.38873015],
       [ 1.        ,  0.        ,  0.        ,  5.        ,  6.        ,
         0.        ,  0.70710678],
       [ 1.        ,  0.        ,  1.        ,  7.        ,  8.        ,
         0.46291005,  0.46291005],
       [ 2.        ,  0.        ,  0.        ,  9.        ,  6.        ,
         1.22474487,  0.70710678],
       [ 2.        ,  0.        ,  1.        ,  8.        ,  9.        ,
         0.9258201 ,  0.9258201 ],
       [ 3.        ,         nan,         nan,         nan,         nan,
                nan,         nan]])

для n уникальных значений в a[:,2]

N = np.unique(a[:,2])[~np.isnan(np.unique(a[:,2]))]
zTemp = [np.fromfunction(lambda i, j: stats.zscore(a[a[:,2] == k][:,3:]), (1, 1)) for k in N]
z=np.zeros((a.shape[0], zTemp[0].shape[1]))*np.nan
for i in range(len(zTemp)):
    z[i::2][:z1.shape[0]]=zTemp[i]
arr1 = np.column_stack((a,z))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...