Python 变换矩阵
我得到了下面的小numpy矩阵,矩阵的值只能是0或1。我使用的实际矩阵的大小实际上要大得多,但是为了演示的目的,这个矩阵是可以的。它的形状是Python 变换矩阵,python,numpy,Python,Numpy,我得到了下面的小numpy矩阵,矩阵的值只能是0或1。我使用的实际矩阵的大小实际上要大得多,但是为了演示的目的,这个矩阵是可以的。它的形状是(8,11) 我需要以这样的方式对其进行更改,以便对于每一列,只有一行的值为1。因此,如果同一列中有更多值为1的行,则保留值为1的最高行,其余行替换为0。 以下是我想要的结果: np_array1 = np.matrix( [[0,0,0,0,1,0,0,0,0,0,0], [0,0,0,1,0,1,0,0,0,0,0], [0,0,0
(8,11)
我需要以这样的方式对其进行更改,以便对于每一列,只有一行的值为1。因此,如果同一列中有更多值为1的行,则保留值为1的最高行,其余行替换为0。
以下是我想要的结果:
np_array1 = np.matrix(
[[0,0,0,0,1,0,0,0,0,0,0],
[0,0,0,1,0,1,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0],
[0,0,1,0,0,0,1,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0],
[0,1,0,0,0,0,0,1,0,1,1],
[0,0,0,0,0,0,0,0,0,0,0],
[1,0,0,0,0,0,0,0,1,0,0]]
)
基本上,每列可以有一个值1,如果有多行,则保留最高的一行。我必须提到的是,也可以有列,其中没有一行的值为1。这些列必须保持不变。矩阵的形状必须与转换前完全相同。这里有一种方法-
def per_col(a):
idx = a.argmax(0)
out = np.zeros_like(a)
r = np.arange(a.shape[1])
out[idx, r] = a[idx, r]
return out
样本运行
案例1:
案例2(插入一个全零列):
如果你对其中一行或是<代码>广播的粉丝着迷,下面是另一个-
((a.argmax(0) == np.arange(a.shape[0])[:,None]).astype(int))*a.any(0)
样本运行-
In [89]: a
Out[89]:
array([[0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1],
[0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0],
[1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0]])
In [90]: ((a.argmax(0) == np.arange(a.shape[0])[:,None]).astype(int))*a.any(0)
Out[90]:
array([[0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0]])
运行时测试-
In [98]: a = np.random.randint(0,2,(100,10000))
# @DSM's soln
In [99]: %timeit ((a == 1) & (a.cumsum(axis=0) == 1)).astype(int)
100 loops, best of 3: 5.19 ms per loop
# Proposed in this post : soln1
In [100]: %timeit per_col(a)
100 loops, best of 3: 3.4 ms per loop
# Proposed in this post : soln2
In [101]: %timeit ((a.argmax(0) == np.arange(a.shape[0])[:,None]).astype(int))*a.any(0)
100 loops, best of 3: 7.73 ms per loop
您可以使用
cumsum
计算您看到的1的数量,然后选择第一个:
In [42]: arr.cumsum(axis=0)
Out[42]:
matrix([[0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 2, 1, 2, 0, 0, 0, 0, 0],
[0, 0, 1, 2, 1, 3, 1, 0, 0, 0, 0],
[0, 0, 2, 2, 1, 3, 2, 0, 0, 0, 0],
[0, 1, 2, 2, 1, 3, 3, 1, 0, 1, 1],
[0, 2, 2, 2, 1, 3, 3, 2, 0, 2, 1],
[1, 2, 2, 2, 1, 3, 3, 3, 1, 3, 1]])
因此
In [43]: ((arr == 1) & (arr.cumsum(axis=0) == 1)).astype(int)
Out[43]:
matrix([[0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0]])
另一种方法是:
for i in range(a.shape[1]):
a[np.where(a[:,i]==1)[0][1:],i] = 0
输出:
[[0 0 0 0 1 0 0 0 0 0 0]
[0 0 0 1 0 1 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0 0]
[0 0 1 0 0 0 1 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0 0]
[0 1 0 0 0 0 0 1 0 1 1]
[0 0 0 0 0 0 0 0 0 0 0]
[1 0 0 0 0 0 0 0 1 0 0]]
[[0 0 0 0 1 0 0 0 0 0 0]
[0 0 0 1 0 1 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0 0]
[0 0 1 0 0 0 1 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0 0]
[0 1 0 0 0 0 0 1 0 1 1]
[0 0 0 0 0 0 0 0 0 0 0]
[1 0 0 0 0 0 0 0 1 0 0]]
您可以使用非零和唯一函数:
c, r = np.nonzero(np_array.T)
_, ind = np.unique(c, return_index=True)
np_array[:] = 0
np_array[r[ind], c[ind]] = 1
给出示例,结果如下:
[[0 0 0 0 1 0 0 0 0 0 0]
[0 0 0 1 0 1 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0 0]
[0 0 1 0 0 0 1 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0 0]
[0 1 0 0 0 0 0 1 0 1 1]
[0 0 0 0 0 0 0 0 0 0 0]
[1 0 0 0 0 0 0 0 1 0 0]]
c, r = np.nonzero(np_array.T)
_, ind = np.unique(c, return_index=True)
np_array[:] = 0
np_array[r[ind], c[ind]] = 1
[[0 0 0 0 1 0 0 0 0 0 0]
[0 0 0 1 0 1 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0 0]
[0 0 1 0 0 0 1 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0 0]
[0 1 0 0 0 0 0 1 0 1 1]
[0 0 0 0 0 0 0 0 0 0 0]
[1 0 0 0 0 0 0 0 1 0 0]]