使用Python替换矩阵中的特定值

3

我有一个m x n的矩阵,每行代表一个样本,每列代表一个类别。每行包含每个类别的软最大值概率。我想要将每行中的最大值替换为1,其他值替换为0。在Python中如何高效地完成这个任务?

4个回答

2

一些虚构的数据:

>>> a = np.random.rand(5, 5)
>>> a
array([[ 0.06922196,  0.66444783,  0.2582146 ,  0.03886282,  0.75403153],
       [ 0.74530361,  0.36357237,  0.3689877 ,  0.71927017,  0.55944165],
       [ 0.84674582,  0.2834574 ,  0.11472191,  0.29572721,  0.03846353],
       [ 0.10322931,  0.90932896,  0.03913152,  0.50660894,  0.45083403],
       [ 0.55196367,  0.92418942,  0.38171512,  0.01016748,  0.04845774]])

在一行中:
>>> (a == a.max(axis=1)[:, None]).astype(int)
array([[0, 0, 0, 0, 1],
       [1, 0, 0, 0, 0],
       [1, 0, 0, 0, 0],
       [0, 1, 0, 0, 0],
       [0, 1, 0, 0, 0]])

一种更高效(且冗长)的方法:
>>> b = np.zeros_like(a, dtype=int)
>>> b[np.arange(a.shape[0]), np.argmax(a, axis=1)] = 1
>>> b
array([[0, 0, 0, 0, 1],
       [1, 0, 0, 0, 0],
       [1, 0, 0, 0, 0],
       [0, 1, 0, 0, 0],
       [0, 1, 0, 0, 0]])

非常好的答案!谢谢 :) - Matrix
好答案,加一。 - Russia Must Remove Putin

1
我认为对于你的问题,最好的答案是使用矩阵类型对象。
稀疏矩阵应该是在存储大量这些大型矩阵时以一种内存友好的方式表现最佳,因为大多数矩阵都被填充了零。这应该比直接使用numpy数组更优,特别是对于两个维度都非常大的矩阵,即使在计算速度方面不如numpy数组,在内存方面也会更好。
import numpy as np
import scipy       #older versions may require `import scipy.sparse`

matrix = np.matrix(np.random.randn(10, 5))
maxes = matrix.argmax(axis=1).A1           
                      # was .A[:,0], slightly faster, but .A1 seems more readable
n_rows = len(matrix)  # could do matrix.shape[0], but that's slower
data = np.ones(n_rows)
row = np.arange(n_rows)
sparse_matrix = scipy.sparse.coo_matrix((data, (row, maxes)), 
                                        shape=matrix.shape, 
                                        dtype=np.int8)

相对于普通矩阵对象,这个稀疏矩阵对象应该非常轻量级,后者会不必要地跟踪其中的每一个零。要将其实例化为普通矩阵:

sparse_matrix.todense()

返回:
matrix([[0, 0, 0, 0, 1],
        [0, 0, 1, 0, 0],
        [0, 0, 1, 0, 0],
        [0, 0, 0, 0, 1],
        [1, 0, 0, 0, 0],
        [0, 0, 1, 0, 0],
        [0, 0, 0, 1, 0],
        [0, 1, 0, 0, 0],
        [1, 0, 0, 0, 0],
        [0, 0, 0, 1, 0]], dtype=int8)

我们可以将其与矩阵进行比较:
matrix([[ 1.41049496,  0.24737968, -0.70849012,  0.24794031,  1.9231408 ],
        [-0.08323096, -0.32134873,  2.14154425, -1.30430663,  0.64934781],
        [ 0.56249379,  0.07851507,  0.63024234, -0.38683508, -1.75887624],
        [-0.41063182,  0.15657594,  0.11175805,  0.37646245,  1.58261556],
        [ 1.10421356, -0.26151637,  0.64442885, -1.23544526, -0.91119517],
        [ 0.51384883,  1.5901419 ,  1.92496778, -1.23541699,  1.00231508],
        [-2.42759787, -0.23592018, -0.33534536,  0.17577329, -1.14793293],
        [-0.06051458,  1.24004714,  1.23588228, -0.11727146, -0.02627196],
        [ 1.66071534, -0.07734444,  1.40305686, -1.02098911, -1.10752638],
        [ 0.12466003, -1.60874191,  1.81127175,  2.26257234, -1.26008476]])

1
在内存使用方面真的非常出色!非常感谢 :-) - Matrix
1
@Matrix,感谢你提出这个好问题,我从回答它中获益良多。继续保持。 - Russia Must Remove Putin

0
Y = np.random.rand(10,10)
X=np.zeros ((5,5))
y_insert=2
x_insert=3
offset = (1,2)
for index_x, row in enumerate(X):
  for index_y, e in enumerate(row):
    Y[index_x + offset[0]][index_y + offset[1]] = e

0

这种使用基本的numpy和列表推导式的方法是可行的,但性能最低。我将保留此答案,因为它可能有一定的指导意义。首先,我们创建一个numpy矩阵:

matrix = np.matrix(np.random.randn(2,2))

matrix 是一个例子:

matrix([[-0.84558168,  0.08836042],
        [-0.01963479,  0.35331933]])

如果元素是最大值,则将1映射到一个新矩阵中,否则为0:

newmatrix = np.matrix([[1 if i == row.max() else 0 for i in row] 
                                                   for row in np.array(matrix)])

newmatrix现在是:

matrix([[0, 1],
        [0, 1]])

@Matrix 我正在尝试想出更好的方法。Jaime 目前比我强,但我正在着手解决一个能够提供高性能替代方案的问题,如果/当我解决它时,我将揭示它。 - Russia Must Remove Putin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接