将多类数组投影到二进制矩阵中

Kir*_*rst 2 python numpy matrix binary-matrix

我有一个简单numpy的阵列(例如[1,4,2,3,1]),并希望将其投影成一个二进制矩阵,其中所述阵列中的每个值映射到在矩阵的该列的指示符。

例如,这个数组将映射到一个矩阵,如:

[1], => [1,0,0,0],
[4],    [0,0,0,1],
[2],    [0,1,0,0],
[3],    [0,0,1,0],
[1]     [1,0,0,0]
Run Code Online (Sandbox Code Playgroud)

我可以通过迭代和列表推导来做到这一点,但是有没有优雅的 numpy 解决方案?

Div*_*kar 5

我们可以使用broadacsting——

(a[:,None] == np.arange(a.max())+1).astype(int)
Run Code Online (Sandbox Code Playgroud)

样品运行 -

In [28]: a = np.array([1,4,2,3,1,2,1,4])

In [29]: a[:,None] == np.arange(a.max())+1 # Booelan array
Out[29]: 
array([[ True, False, False, False],
       [False, False, False,  True],
       [False,  True, False, False],
       [False, False,  True, False],
       [ True, False, False, False],
       [False,  True, False, False],
       [ True, False, False, False],
       [False, False, False,  True]], dtype=bool)

In [30]: (a[:,None] == np.arange(a.max())+1).astype(int) # Int array
Out[30]: 
array([[1, 0, 0, 0],
       [0, 0, 0, 1],
       [0, 1, 0, 0],
       [0, 0, 1, 0],
       [1, 0, 0, 0],
       [0, 1, 0, 0],
       [1, 0, 0, 0],
       [0, 0, 0, 1]])
Run Code Online (Sandbox Code Playgroud)

对于映射非连续且不期望所有False列的整数,我们可以np.unique(a)直接使用2D与输入数组的版本进行比较a,如下所示 -

In [49]: a = np.array([14,12,33,71,97])

In [50]: a[:,None] == np.unique(a) # Boolean array
Out[50]: 
array([[False,  True, False, False, False],
       [ True, False, False, False, False],
       [False, False,  True, False, False],
       [False, False, False,  True, False],
       [False, False, False, False,  True]], dtype=bool)

In [51]: (a[:,None] == np.unique(a)).astype(int) # Int array
Out[51]: 
array([[0, 1, 0, 0, 0],
       [1, 0, 0, 0, 0],
       [0, 0, 1, 0, 0],
       [0, 0, 0, 1, 0],
       [0, 0, 0, 0, 1]])
Run Code Online (Sandbox Code Playgroud)