2012-02-20 4 views
2

Учитывая матрицу А с формой (1000000,6) я понял, как получить минимальное правое значение для каждой строки и реализовали его в этой функции:Numpy: Как избавиться от минимумов вдоль оси = 1, учитывая показатели - эффективным образом?

def calculate_row_minima_indices(h): # h is the given matrix. 
    """Returns the indices of the rightmost minimum per row for matrix h.""" 
    flipped = numpy.fliplr(h) # flip the matrix to get the rightmost minimum. 
    flipped_indices = numpy.argmin(flipped, axis=1) 
    indices = numpy.array([2]*dim) - flipped_indices 
    return indices 

indices = calculate_row_minima_indices(h) 
for col, row in enumerate(indices): 
    print col, row, h[col][row] # col_index, row_index and value of minimum which should be removed. 

Каждая строка имеет минимум. Так что мне нужно знать, чтобы удалить запись с минимальным и сжиматься матрицы с формы (1000000,6) к матрице с формы (1000000,5).

Я бы сгенерировал новую матрицу с меньшим размером и заполнил ее значениями, которые я хочу, чтобы они несли с помощью цикла for, но я боюсь времени выполнения. Так есть какой-то встроенный способ или какой-то трюк, чтобы уменьшить матрицу по минимумам в строке?

Возможно, эта информация используется: значения все больше или равны 0.0.

ответ

1

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

import numpy as np 

def main(): 
    np.random.seed(1) # For reproducibility 
    data = generate_data((10, 6)) 

    indices = rightmost_min_col(data) 
    new_data = pop_col(data, indices) 

    print 'Original data...' 
    print data 
    print 'Modified data...' 
    print new_data 

def generate_data(shape): 
    return np.random.randint(0, 10, shape) 

def rightmost_min_col(data): 
    nrows, ncols = data.shape[:2] 
    min_indices = np.fliplr(data).argmin(axis=1) 
    min_indices = (ncols - 1) - min_indices 
    return min_indices 

def pop_col(data, col_indices): 
    nrows, ncols = data.shape[:2] 
    col_indices = col_indices[:, np.newaxis] 
    row_indices = np.arange(ncols)[np.newaxis, :] 
    mask = col_indices != row_indices 
    return data[mask].reshape((nrows, ncols-1)) 

if __name__ == '__main__': 
    main() 

Это дает:

Original data... 
[[5 8 9 5 0 0] 
[1 7 6 9 2 4] 
[5 2 4 2 4 7] 
[7 9 1 7 0 6] 
[9 9 7 6 9 1] 
[0 1 8 8 3 9] 
[8 7 3 6 5 1] 
[9 3 4 8 1 4] 
[0 3 9 2 0 4] 
[9 2 7 7 9 8]] 
Modified data... 
[[5 8 9 5 0] 
[7 6 9 2 4] 
[5 2 4 4 7] 
[7 9 1 7 6] 
[9 9 7 6 9] 
[1 8 8 3 9] 
[8 7 3 6 5] 
[9 3 4 8 4] 
[0 3 9 2 4] 
[9 7 7 9 8]] 

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

import numpy as np 
a = np.array([[1, 2, 3]]) 
b = np.array([[1],[2],[3]]) 
print a == b 

Это дает:

array([[ True, False, False], 
     [False, True, False], 
     [False, False, True]], dtype=bool) 

Таким образом, если мы знаем, что индекс столбца элемента, мы хотим удалить, мы можем векторизации операцию для массива индексы столбцов, что и делает pop_col.

+1

Вы можете сделать 'mask = np.ones (data.shape, 'bool'); mask [np.arange (nrows), col_indices] = False'. Это может быть более читаемым. –

+0

Это не делает то же самое. –

+0

Кажется, что то же самое, не могли бы вы объяснить, как они отличаются? –

1

Вы можете использовать массив маски bool, чтобы сделать выбор, но использование памяти немного велико.

import numpy 

h = numpy.random.randint(0, 10, (20, 6)) 

flipped = numpy.fliplr(h) # flip the matrix to get the rightmost minimum. 
flipped_indices = numpy.argmin(flipped, axis=1) 
indices = 5 - flipped_indices 

mask = numpy.ones(h.shape, numpy.bool) 

mask[numpy.arange(h.shape[0]), indices] = False 

result = h[mask].reshape(-1, 5) 

 Смежные вопросы

  • Нет связанных вопросов^_^