将numpy数组解析为二进制数组

时间:2014-04-07 09:28:48

标签: python arrays numpy

我有一个numpy数组

[0 0 0 0 0 0 0 1 1 2 2 2 2 2 1 1 0 0 0 0 0 0 0 0]

我想转换/解散为

[[0 0 0 0 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 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 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 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 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 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 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 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 0 0 1 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 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 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 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 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 0 0 1 0 0 0 0 0 0 0 0 0 0]]

我目前的方法是先使用while循环将数组拆分为1,然后根据np.where(x>0)创建一个数组。但我相信这不是最有效和优雅的numpy解决方案。关于如何改进的任何想法?

source = np.array([0., 0., 0., 0., 0., 0., 0., 1., 1., 2., 2., 2., 2.,
                   2., 1., 1., 0., 0., 0., 0., 0., 0., 0., 0.], dtype=np.int)

diss = None
while np.any(source):
    row = np.greater(source, 0).astype(np.int)
    if diss is None:
        diss = row
    else:
        diss = np.vstack([diss, row])
    source -= row

idx = np.where(diss > 0)
result = np.zeros((0,source.shape[0]), dtype=np.int)
for x, y in zip(*idx):
    row = np.zeros(source.shape, dtype=np.int)
    row[y] = 1
    result = np.vstack([result, row])

2 个答案:

答案 0 :(得分:2)

对于您的示例,这大约快5倍,并且不会对source造成损害。

source = np.array([0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 2, 2, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0], int)
m, h, w = source.max(), source.sum(), len(source)
i = np.concatenate([np.nonzero(source>i)[0] for i in xrange(m)])
result = np.zeros((h,w), int)
result[range(h), i] = 1

还有一个长度为source.max()的循环,所以如果它很大(例如它只有两个),也许可以做得更好。

答案 1 :(得分:2)

以这种方式:

In [38]: x = np.array([0,0,0,0,0,1,1,2,2,2,1,1,0,0])

In [39]: n = x.sum()

In [40]: rows = np.arange(n)

In [41]: positions = np.nonzero(x)[0]

In [42]: cols = np.repeat(positions, x[positions])

In [43]: result = np.zeros((n, len(x)), dtype=int)

In [44]: result[rows, cols] = 1

In [45]: result
Out[45]: 
array([[0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0]])