Получение количества предметов под диагональю в numpy - PullRequest
1 голос
/ 01 мая 2019

У меня есть корреляционная матрица, и я хочу получить количество элементов ниже диагонали. Желательно в NumPy.

[[1,   0,   0,   0,  0], 
[.35,  1,   0,   0,  0], 
[.42, .31,  1,   0,  0], 
[.25, .38, .41,  1,  0], 
[.21, .36, .46, .31, 1]]

Я хочу, чтобы он вернул 10. Или, чтобы вернуть среднее значение всех чисел под диагональю.

Ответы [ 2 ]

2 голосов
/ 01 мая 2019

Более примитивный и громоздкий ответ, так как numpy обеспечивает np.tril_indices, как упомянуло user3483203, но то, что вы хотите для каждой итерации строки, i следующее (с точки зрения индексов [row, col]):

                      (i=0)
[1,0]                 (i=1) 
[2,0] [2,1]           (i=2)
[3,0] [3,1] [3,2]     (i=3)
...

Это, по сути, zip списка [i,i,i,...] = [i]*i (i повторений i) с [0,1,...,i-1] = range(i). Таким образом, итерируя по строкам таблицы, вы можете получить индексы для каждой итерации и выполнить оператор по вашему выбору.

Пример настройки:

test = np.array(
[[1,   0,   0,   0,  0], 
[.35,  1,   0,   0,  0], 
[.42, .31,  1,   0,  0], 
[.25, .38, .41,  1,  0], 
[.21, .36, .46, .31, 1]])

Определение функции:

def countdiag(myarray):
    numvals = 0
    totsum = 0


    for i in range(myarray.shape[0]): # row iteration
        colc = np.array(range(i)) # calculate column indices
        rowc = np.array([i]*i) # calculate row indices

        if any(rowc):
            print(np.sum(myarray[rowc,colc]))
            print(len(myarray[rowc,colc]))

            numvals += len(myarray[rowc,colc])
            totsum += np.sum(myarray[rowc,colc])


        print(list(zip([i]*i, np.arange(i))))

    mean = totsum / numvals

    return mean, numvals

Тест:

 [165]: countdiag(test)



[]
0.35
1
[(1, 0)]
0.73
2
[(2, 0), (2, 1)]
1.04
3
[(3, 0), (3, 1), (3, 2)]
1.34
4
[(4, 0), (4, 1), (4, 2), (4, 3)]
0.346
Out[165]:
(0.346, 10)
2 голосов
/ 01 мая 2019

Настройка

a = np.array([[1.  , 0.  , 0.  , 0.  , 0.  ],
              [0.35, 1.  , 0.  , 0.  , 0.  ],
              [0.42, 0.31, 1.  , 0.  , 0.  ],
              [0.25, 0.38, 0.41, 1.  , 0.  ],
              [0.21, 0.36, 0.46, 0.31, 1.  ]])

numpy.tril_indices даст индексы всех элементов под диагональю (если выпредоставить смещение -1), и оттуда это становится так же просто, как индексирование и вызов mean и size


n, m = a.shape

m = np.tril_indices(n=n, k=-1, m=m)

a[m]
# array([0.35, 0.42, 0.31, 0.25, 0.38, 0.41, 0.21, 0.36, 0.46, 0.31])

a[m].mean()
# 0.346

a[m].size
# 10
...