Numpy:如何在给定指数的情况下有效地去除轴=1的最小值?

2024-10-04 05:33:19 发布

您现在位置:Python中文网/ 问答频道 /正文

给定一个形状为(1000000,6)的矩阵a,我已经找到了如何获得每行的最小最右边值,并在函数中实现了它:

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可能等于所有信息的值。在


Tags: ofthenumpyfor矩阵colmatrixrow
2条回答

您可以使用boolmask数组进行选择,但是内存使用量有点大。在

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)

假设您有足够的内存来保存布尔掩码(原始数组和新数组的形状),下面是一种方法:

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()

这就产生了:

^{pr2}$

我在这里使用的一个不太可读的技巧是在数组比较期间利用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所做的。在

相关问题 更多 >